<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Designfrage: Pool]]></title><description><![CDATA[<p>Hallo!<br />
ich benötige für meinen Server Thread- u. Socketpools und habe deshalb beschlossen, eine Klasse dafür zu schreiben. Später sollen dann verschiedene Threads auf den Pool zugreifen, ein Element des Pools benutzen und wenn sie fertig sind wieder zurücklegen. Das ist mein grober Entwurf:</p>
<pre><code class="language-cpp">template &lt;typename HTy_&gt;
class pool {
public:
	typedef typename std::list&lt;HTy_&gt;::iterator iterator;

	template &lt;typename Fnc_&gt;
	pool(unsigned poolsize, const Fnc_&amp; fnc) {
		while(--poolsize) unused_.push(fnc());
	}

	const iterator get() {
		used_.push_front(unused_.front());
		unused_.pop();
		return used.begin();
	}

	void putback(iterator) {
		unused_.push(*iterator);
		used_.erase(iterator);
	}

private:
	std::queue&lt;HTy_&gt; unused_;
	std::list&lt;HTy_&gt; used_;
};
</code></pre>
<p>Da die gespeicherten Handles ja entweder benutzt o. gerade nicht benutzt werden, hatte ich die Idee sie jeweils zwischen den Containern hin und her zu moven. Aber schon die Wahl der Container fiel mir hier schwer und ich bin mir nicht sicher, ob ich mir damit noch irgendwann einen Strick gedreht habe.<br />
Also, gibt es bei diesem Entwurf irgendwo eine Falle, die mir später Kopfschmerzen bereiten kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/269119/designfrage-pool</link><generator>RSS for Node</generator><lastBuildDate>Mon, 31 Aug 2026 08:56:01 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/269119.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 19 Jun 2010 12:22:10 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 12:22:10 GMT]]></title><description><![CDATA[<p>Hallo!<br />
ich benötige für meinen Server Thread- u. Socketpools und habe deshalb beschlossen, eine Klasse dafür zu schreiben. Später sollen dann verschiedene Threads auf den Pool zugreifen, ein Element des Pools benutzen und wenn sie fertig sind wieder zurücklegen. Das ist mein grober Entwurf:</p>
<pre><code class="language-cpp">template &lt;typename HTy_&gt;
class pool {
public:
	typedef typename std::list&lt;HTy_&gt;::iterator iterator;

	template &lt;typename Fnc_&gt;
	pool(unsigned poolsize, const Fnc_&amp; fnc) {
		while(--poolsize) unused_.push(fnc());
	}

	const iterator get() {
		used_.push_front(unused_.front());
		unused_.pop();
		return used.begin();
	}

	void putback(iterator) {
		unused_.push(*iterator);
		used_.erase(iterator);
	}

private:
	std::queue&lt;HTy_&gt; unused_;
	std::list&lt;HTy_&gt; used_;
};
</code></pre>
<p>Da die gespeicherten Handles ja entweder benutzt o. gerade nicht benutzt werden, hatte ich die Idee sie jeweils zwischen den Containern hin und her zu moven. Aber schon die Wahl der Container fiel mir hier schwer und ich bin mir nicht sicher, ob ich mir damit noch irgendwann einen Strick gedreht habe.<br />
Also, gibt es bei diesem Entwurf irgendwo eine Falle, die mir später Kopfschmerzen bereiten kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914711</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914711</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 12:22:10 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 12:32:12 GMT]]></title><description><![CDATA[<p>Da der Pool von mehreren Threads benutzt wird, muss der Zugriff synchronisiert werden. Je nachdem wie oft darauf zugegriffen wird, bzw. wie lange eine Resource benutzt wird, kann das mehr oder minder den parallelen Ablauf stoeren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914715</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914715</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Sat, 19 Jun 2010 12:32:12 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 12:35:50 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; muss der Zugriff synchronisiert werden.</p>
</blockquote>
<p>Was genau heißt das? Ich hatte vor, dass jeder Thread einen Zeiger auf den selben Speicherbereich (der, wo der Pool liegt) bekommt. Dann müsste der Pool doch bei jedem Thread synchron, also gleich sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914719</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914719</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 12:35:50 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 12:53:55 GMT]]></title><description><![CDATA[<p>Das sind Grundlagen, die du dir selbst aneignen musst. Hier ein Link zum Starten: <a href="http://de.wikipedia.org/wiki/Race_Condition" rel="nofollow">http://de.wikipedia.org/wiki/Race_Condition</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914725</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914725</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Sat, 19 Jun 2010 12:53:55 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:23:07 GMT]]></title><description><![CDATA[<p>Hm... okay, ich habe das jetzt so umgeändert:</p>
<pre><code class="language-cpp">template &lt;typename HTy_&gt;
class pool {
public:
	typedef typename std::list&lt;HTy_&gt;::iterator iterator;

	template &lt;typename Fnc_&gt;
	pool(unsigned poolsize, const Fnc_&amp; fnc)
	{
		while(--poolsize) unused_.push(fnc());
	}

	const iterator get() {
		mutex lock;
		used_.push_front(unused_.front());
		unused_.pop();
		return used.begin();
	}

	void putback(iterator) {
		mutex lock;
		unused_.push(*iterator);
		used_.erase(iterator);
	}

private:
	std::queue&lt;HTy_&gt; unused_;
	std::list&lt;HTy_&gt; used_;
};
</code></pre>
<p>Hoffentlich geht das gut... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914737</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914737</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:23:07 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:26:55 GMT]]></title><description><![CDATA[<p>was soll &quot;mutex lock;&quot; sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914739</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914739</guid><dc:creator><![CDATA[und]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:26:55 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:34:29 GMT]]></title><description><![CDATA[<p>Na so ein Lock-Teil, das ich anderswo definiert habe. Wäre aber Windows-spezifisch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914740</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914740</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:34:29 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:37:59 GMT]]></title><description><![CDATA[<p>.. habe meine Antwort versucht klarer zu schreiben.. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /></p>
<p>Edit:<br />
Andersrum: Du musst pro zu lockenden Bereich (also einen Bereich auf welchen nur 1 Thread gleichzeitig zugreifen kann) ein Mutex Objekt haben. Bedeutet, dein Objekt lock muss ein Member sein!</p>
<p>Simon</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914741</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:37:59 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:38:14 GMT]]></title><description><![CDATA[<p>Deshalb besitzt mutex ja im Innern ein statisches Objekt. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /> Der Konstruktor is blockierend, fals dieses Objekt im &quot;locked&quot;-mode steht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914743</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914743</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:38:14 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:45:15 GMT]]></title><description><![CDATA[<p>Aha.. aber Du willst ja nicht alle Pool Instanzen auch gleich mitlocken, wenn Du bei einer bestimmten Pool Instanz ein Objekt rausholst.</p>
<p>Edit:<br />
Typeischerweise geht das in etwa so:<br />
1. Es gibt ein Mutex Objekt (CriticalSection, Mutex, etc.) pro zu schützenden &quot;Bereich&quot;, in deinem Fall ein Objekt vom Typ pool.<br />
2. Jede Methode die den schützenswerten Bereich &quot;anfassen&quot; möchte, versucht dieses Mutex Objekt zu locken und wird es danach auch wieder freigeben. Das wird oft mittels RAII, z.B. einer Lock Klasse gemacht, welche als Konstruktor Argument eben dieses Mutex Objekt nimmt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914744</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914744</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:45:15 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 13:53:43 GMT]]></title><description><![CDATA[<p>So habe ich es in etwa gemacht:</p>
<pre><code class="language-cpp">template &lt;typename HTy_&gt;
class pool {
public:
    typedef typename std::list&lt;HTy_&gt;::iterator iterator;

    template &lt;typename Fnc_&gt;
    pool(unsigned poolsize, const Fnc_&amp; fnc)
    {
        while(--poolsize) unused_.push(fnc());
    }

    const iterator get() {
        mutex lck(lock_);
        used_.push_front(unused_.front());
        unused_.pop();
        return used.begin();
    }

    void putback(iterator) {
        mutex lck(lock_);
        unused_.push(*iterator);
        used_.erase(iterator);
    }

private:
    mutex lock_;
    std::queue&lt;HTy_&gt; unused_;
    std::list&lt;HTy_&gt; used_;
};
</code></pre>
<p>Jetzt in Ordnung?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914746</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914746</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 13:53:43 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 14:08:07 GMT]]></title><description><![CDATA[<p>Ohne genau zu wissen was dein &quot;mutex&quot; ist, kann das keiner sagen, aber das was hier nach nem Copyctor aussieht ist dann wohl falsch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914752</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914752</guid><dc:creator><![CDATA[und]]></dc:creator><pubDate>Sat, 19 Jun 2010 14:08:07 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 14:30:07 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; Ohne genau zu wissen was dein &quot;mutex&quot; ist,</p>
</blockquote>
<p>Da nicht alle Leute Win32-API können, bringt es nichts, den Code zu posten.</p>
<blockquote>
<p>&gt; aber das was hier nach nem Copyctor aussieht ist dann wohl falsch.</p>
</blockquote>
<p>Nö. Der Lock wird kopiert und blockiert dann, wenn gerade jemand anderes dort arbeitet. Wenn der andere fertig ist, hört der Copy-Ctor auf zu warten und blockiert nun selber und returned. Der Dtor von der Kopie hebt die Blockade dann wieder auf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914765</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914765</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 14:30:07 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 14:48:22 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; Ohne genau zu wissen was dein &quot;mutex&quot; ist,</p>
</blockquote>
<p>Da nicht alle Leute Win32-API können, bringt es nichts, den Code zu posten.</p>
</blockquote>
<p>dann können wir auch nix machen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914782</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914782</guid><dc:creator><![CDATA[und]]></dc:creator><pubDate>Sat, 19 Jun 2010 14:48:22 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 14:53:14 GMT]]></title><description><![CDATA[<p>Mir egal, aber für dieses Forum ist das jetzt nicht treffend:</p>
<pre><code class="language-cpp">class mutex {
public:
	mutex()
           : event_(CreateEvent(0, 0, 0, 0)) {
		SetEvent(event_); // signaled
	}

	mutex(const mutex&amp; m)
		: event_(m.event_) {
		WaitForSingleObject(event_, INFINITE);
		ResetEvent(event_); // Nicht signaled
	}

	~mutex() { SetEvent(event_); } // signaled

private:
	HANDLE event_;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1914784</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914784</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 14:53:14 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 14:56:00 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<p>Jetzt in Ordnung?</p>
</blockquote>
<p>Nein, du darfst keinen iterator auf den pool nach aussen geben.<br />
Davon abgesehen hast du hier ja keinen relevanten Code, also kann man nichts sagen. Aber der Ansatz sieht etwas schief aus. Vorallem der mutex Code und der Ctor.</p>
<p>Weiters musst du mit Proxys der Resourcen arbeiten, du willst ja nicht dauernd kopieren - vorallem sind nicht alle Resourcen kopierbar...</p>
<p>Die used Liste brauchst du im Prinzip auch nur wenn du garbage collection machen willst.</p>
<p>Vielleicht waere etwas mehr Code schon sinnvoll, denn da ist nichts worueber wir sinnvoll reden koennten, mit Ausnahme ob man eine used-Liste braucht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914785</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Sat, 19 Jun 2010 14:56:00 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 15:04:54 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; Nein, du darfst keinen iterator auf den pool nach aussen geben.</p>
</blockquote>
<p>Warum?</p>
<blockquote>
<p>&gt; Davon abgesehen hast du hier ja keinen relevanten Code, also kann man nichts sagen.</p>
</blockquote>
<p>Anwendungsfall wäre:</p>
<pre><code class="language-cpp">typedef std::shared_ptr&lt;socket&gt; socket_ptr;
pool&lt;socket_ptr&gt; socket_pool(5, create_socket); // create_socket ist eine Funktion
// ...
for(;;) {
   pool&lt;socket_ptr&gt;::iterator accept_socket = socket_pool.get(); // freien Socket bekommen
   accept(*accept_socket); // Verbindung aufnehmen
   service(*accpet_socket); // Verbindung bearbeiten bis zum disconnect
   socket_pool.putback(accept_socket); // Socket zurücklegen
}
</code></pre>
<p>Zugegeben, das Dereferenzieren sieht nicht schön aus, aber wo ist das Problem mit einem Iterator?</p>
<blockquote>
<p>&gt; Weiters musst du mit Proxys der Resourcen arbeiten, du willst ja nicht dauernd kopieren</p>
</blockquote>
<p>Ich habe sowohl Wrapper um die Handles alsauch shared_ptr.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914790</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914790</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 15:04:54 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 15:08:49 GMT]]></title><description><![CDATA[<p>was soll dein mutex jetzt machen außer ewig warten im copyctor?<br />
schau dir mal das an<br />
<a href="http://msdn.microsoft.com/en-us/library/ms686927%28VS.85%29.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ms686927(VS.85).aspx</a><br />
und so geht ein scoped lock<br />
<a href="http://www.boost.org/doc/libs/1_35_0/doc/html/boost/interprocess/scoped_lock.html" rel="nofollow">http://www.boost.org/doc/libs/1_35_0/doc/html/boost/interprocess/scoped_lock.html</a></p>
<p>Ad aCTa schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; Nein, du darfst keinen iterator auf den pool nach aussen geben.</p>
</blockquote>
<p>Warum?</p>
</blockquote>
<p>weil man damit alles möglich ein deinem pool machen kann, am mutex vorbei usw..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914792</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914792</guid><dc:creator><![CDATA[und]]></dc:creator><pubDate>Sat, 19 Jun 2010 15:08:49 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 15:26:00 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; was soll dein mutex jetzt machen außer ewig warten im copyctor?</p>
</blockquote>
<p>Das Event umschalten (non-signaled), damit ein weiterer Lock jetzt warten muss. Davor wartet er solange, bis ein anderer Thread das Event auf signaled stellt. (Genau dann wenn der Dtor eines anderen Locks aufgerufen wurde.) Was soll daran nicht stimmen?</p>
<blockquote>
<p>&gt; weil man damit alles möglich ein deinem pool machen kann, am mutex vorbei usw..</p>
</blockquote>
<p>Was will man denn machen? Der Iterator ist konstant, der Pool kann durch ihn nicht verändert werden. Er hat nur Zugriff auf dieses eine Element, und das gehört jetzt dem Thread und muss bis zum putback nicht mehr synchronisiert werden.</p>
<p>Edit: Ja, der Sinn der used-Liste ist schon etwas fraglich. Ich hatte Angst vor Leaks, weil ich dem Nutzer nun das Handle anvertraue und hoffe, dass er es auch wieder in den Pool zurückpackt. Ich könnte das natürlich so machen:</p>
<pre><code class="language-cpp">struct noch_ein_wrapper {
   noch_ein_wrapper(const socket_ptr&amp; ptr, pool&lt;socket_ptr&gt;&amp; p)
      : socket_pool(p), socket(ptr) {
   }

   ~noch_ein_wrapper() { socket_pool.putback(ptr); }

   pool&lt;socket_ptr&gt;&amp; socket_pool;
   socket_ptr socket;
};
</code></pre>
<p>Aber das wäre jetzt schon der 3. Wrapper um das eigentliche Handle...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914795</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914795</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sat, 19 Jun 2010 15:26:00 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 15:25:26 GMT]]></title><description><![CDATA[<p>1. CloseHandle(..) wird nicht aufgerufen bei deiner mutex Implemenation.<br />
2. Benutzt doch die extra dafür vorgesehenen Mechanismen, entweder boost oder direkt Win32 API Critical Section, Mutex, Semaphore, ...</p>
<p>Hier eine Implementation mit Critical Sections um das Prinzip zu Skizieren:</p>
<pre><code class="language-cpp">class CriticalSection
{
public:
    CriticalSection()
    {
      InitializeCriticalSection(&amp;_cs);
    }
    ~CriticalSection()
    {
      DeleteCriticalSection(&amp;_cs);
    }
    void enter() const
    {
      EnterCriticalSection(&amp;_cs);
    }
    void leave() const
    {
      LeaveCriticalSection(&amp;_cs);
    }

private:
    CriticalSection(const CriticalSection&amp;);
    CriticalSection&amp; operator=(const CriticalSection&amp;);

    mutable CRITICAL_SECTION _cs;
};

class CriticalSectionLock
{
public:
    explicit CriticalSectionLock(const CriticalSection&amp; cs)
    : _cs(cs)
    {
      _cs.enter();
    }
    ~CriticalSectionLock()
    {
      _cs.leave();
    }

private:
    CriticalSectionLock(const CriticalSectionLock&amp;);
    CriticalSectionLock&amp; operator=(const CriticalSectionLock&amp;);

    const CriticalSection&amp; _cs;
};
</code></pre>
<p>Simon</p>
<p>PS:</p>
<blockquote>
<p>Da nicht alle Leute Win32-API können, bringt es nichts, den Code zu posten.</p>
</blockquote>
<p>Glaub mir, da wissen ne Menge Leute ganz anderes nicht und es würde nie etwas bringen irgendetwas zu posten.. aber ist ja offensichtlich nicht so...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914801</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914801</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Sat, 19 Jun 2010 15:25:26 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 16:02:36 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; weil man damit alles möglich ein deinem pool machen kann, am mutex vorbei usw..</p>
</blockquote>
<p>Was will man denn machen? Der Iterator ist konstant, der Pool kann durch ihn nicht verändert werden. Er hat nur Zugriff auf dieses eine Element, und das gehört jetzt dem Thread und muss bis zum putback nicht mehr synchronisiert werden.</p>
</blockquote>
<p>Dieses const bringt bei dem iterator garnichts.</p>
<pre><code class="language-cpp">int t=0;
int f(){return t++;}

template &lt;typename HTy_&gt;
class pool {
public:
    typedef typename std::list&lt;HTy_&gt;::iterator iterator;

    template &lt;typename Fnc_&gt;
    pool(unsigned poolsize, const Fnc_&amp; fnc)
    {
        while(--poolsize) unused_.push(fnc());
    }

    const iterator get() {
        used_.push_front(unused_.front());
        unused_.pop();
        return used_.begin();
    }

    void putback(iterator) {
        unused_.push(*iterator);
        used_.erase(iterator);
    }

private:
    std::queue&lt;HTy_&gt; unused_;
    std::list&lt;HTy_&gt; used_;
}; 

int main()
{
	pool&lt;int&gt; p(3,f);
	pool&lt;int&gt;::iterator ittmp = p.get();
	pool&lt;int&gt;::iterator it = p.get();
	std::cout&lt;&lt;*it;
	it++;
	std::cout&lt;&lt;*it;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1914818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914818</guid><dc:creator><![CDATA[und]]></dc:creator><pubDate>Sat, 19 Jun 2010 16:02:36 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sat, 19 Jun 2010 18:21:30 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; Nein, du darfst keinen iterator auf den pool nach aussen geben.</p>
</blockquote>
<p>Warum?</p>
</blockquote>
<p>Weil ich dann einfach ein ++it; mache und boese Sachen machen kann. Weiters hast du ein Implementationsdetail im Interface - das ist meistens schlecht.</p>
<p>Im Normalfall loest man sowas ueber Proxy Objekte. Dein iterator ist ja genauso ein Proxy objekt - nur dass er sich unnatuerlich anfuehlt und so fiese Sachen wie</p>
<pre><code class="language-cpp">*i=some_other_resource;
</code></pre>
<p>erlaubt.</p>
<blockquote>
<blockquote>
<p>&gt; Davon abgesehen hast du hier ja keinen relevanten Code, also kann man nichts sagen.</p>
</blockquote>
<p>Anwendungsfall wäre:</p>
</blockquote>
<p>Und der Code kommt dir nicht komisch vor mit dem iterator? Aber ja, in der Anwendung ist der pool trivial, du hast eine get und eine putback Methode. Das Spannende sind aber die konkreten Implementierungen.</p>
<p>Weiters ist dein Ctor immernoch Fehlerhaft.<br />
Die used Liste kannst du in der Debug Variante ja fuehren. Dann fehlt natuerlich noch ein Dtor und eine schoene delete Funktion fuer die Resourcen.</p>
<p>Dann gibts noch so kleinigkeiten wie zB der Pool sollte nicht kopierbar sein.</p>
<p>Sprich du hast die Idee fuer einen Pool gehabt, das passt. Aber du musst alles zu Ende denken. Aber wenn du das Locking Fehlerfrei machst, die Poolklasse nicht kopierbar machst, die used Liste entfernst, den Fehler im Ctor fixt (uU einen dynamisch wachsenden Pool machst?), einen Dtor implementierst und die iteratoren entfernst - dann passt es so in etwa <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Und ueberdenke wie du Resourcen erstellen willst die nicht kopierbar sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1914858</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1914858</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Sat, 19 Jun 2010 18:21:30 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sun, 20 Jun 2010 10:02:54 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; 1. CloseHandle(..) wird nicht aufgerufen bei deiner mutex Implemenation.</p>
</blockquote>
<p>Guter Punkt, das habe ich jetzt behoben. (Nutze Mutex der Windows API).</p>
<blockquote>
<p>&gt; Weil ich dann einfach ein ++it; mache und boese Sachen machen kann.</p>
</blockquote>
<p>Das wusste ich noch garnicht! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> Dann ist klar, warum das nicht sicher ist...</p>
<blockquote>
<p>&gt; Weiters hast du ein Implementationsdetail im Interface - das ist meistens schlecht.</p>
</blockquote>
<p>Ich weiß, der Code hier ist nur so zur Darstellung. Im echten Code sind sie getrennt. Ich schreibe es jetzt hier aber auch mal getrennt auf.</p>
<p>Die used-Liste ist so gesehen sinnlos. Meine Idee war, dass ich aus der Queue einfach freie Handles bekomme (ohne große Schleifen mit Sachen wie <code>if(iter-&gt;is_used())</code> ) und sie dann daraus entferne. Sobald der Client des pools fertig ist, soll Stack-Unwinding den Destruktor aufrufen, welcher das Handle in den Pool zurückschreibt. Der Pool speichert seine Handles in <code>std::shared_ptr</code> s, die dann auch von pool::get() zurückgegeben werden. Ich hätte gerne sowas:</p>
<pre><code class="language-cpp">template &lt;typename HTy_&gt;
std::shared_ptr&lt;HTy_&gt; pool&lt;HTy_&gt;::get() {
	mutex lck(lock_);
	std::shared_ptr&lt;HTy&gt; tmp(unused_.front().get(), std::bind(&amp;pool&lt;HTy_&gt;::deleter, this, std::placeholders::_1)); // shared_ptr bekommen und Deleter einstellen
	unused_.pop(); // aus Queue entfernen
	return tmp; // Zack! (siehe unten)
}

// ...
{ // Scope
	pool&lt;socket&gt; socket_pool(5, create_socket); // socket ist ein Handle-Wrapper
	typedef std::shared_ptr&lt;socket&gt; socket_ptr;
	socket_ptr socket = socket_pool.get();
	// Service...
} // Scope verlassen, der Deleter von shared_ptr soll das Handle in die Queue zurückschieben
</code></pre>
<p>Der Deleter ist einfach sowas:</p>
<pre><code class="language-cpp">template &lt;typename HTy_&gt;
void pool&lt;HTy_&gt;::deleter(HTy* object) {
	mutex lck(lock_);
	unused_.push(std::shared_ptr&lt;HTy&gt;(object)); // neuen shared_ptr aus der Ressource erstellen + pushen
}
</code></pre>
<p>Oben steht &quot;Zack!&quot;, und zwar weil ja schon der Destruktor des shared_ptr in der pool::get() samt Deleter aufgerufen wird und die Ressource in die Queue zurückschreibt, obwohl sie ja jetzt als &quot;used&quot; gilt. So kann das demnach nicht klappen. Wie kann ich das lösen? (Automatisches zurückschreiben in Queue)</p>
<blockquote>
<p>&gt; die Poolklasse nicht kopierbar machst,</p>
</blockquote>
<p>Kommt danach, erst mal muss der Pool selbst funktionieren. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<blockquote>
<p>&gt; den Fehler im Ctor fixt</p>
</blockquote>
<p>Fehler?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1915009</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1915009</guid><dc:creator><![CDATA[Ad aCTa]]></dc:creator><pubDate>Sun, 20 Jun 2010 10:02:54 GMT</pubDate></item><item><title><![CDATA[Reply to Designfrage: Pool on Sun, 20 Jun 2010 13:14:16 GMT]]></title><description><![CDATA[<p>Ad aCTa schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; den Fehler im Ctor fixt</p>
</blockquote>
<p>Fehler?</p>
</blockquote>
<pre><code class="language-cpp">while(--poolsize) unused_.push(fnc());
</code></pre>
<p>Wieviele Objekte legst du an wenn poolsize zB 1 ist?</p>
<p>-&gt;</p>
<pre><code class="language-cpp">while(poolsize--) unused_.push(fnc());
</code></pre>
<p>PS:<br />
mir persoenlich gefaellt diese shared_ptr Variante nicht so toll weil ich diese Option lieber dem Clientcode ueberlasse, aber im Prinzip passt es so schon.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1915082</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1915082</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Sun, 20 Jun 2010 13:14:16 GMT</pubDate></item></channel></rss>