<?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[Policy benutzen, um Threading-Verhalten in Klasse zu geben]]></title><description><![CDATA[<p>Wo ich gerade schonmal beim Refaktoren bin <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="😉"
    /> würde ich gerne folgendes häßliche Konstrukt eliminieren:</p>
<pre><code class="language-cpp">class Foo {
public:
    void bar() {
#ifdef THREADING_MULTI
        boost::mutex::scoped_lock lock(mutex_);
#endif
        doSomething;
    }
private:
#ifdef THREADING_MULTI
    boost::mutex mutex_;
#endif
};
</code></pre>
<p>Ich erinnere mich dunkel, im Alexandrescu genau so ein Beispiel gelesen zu haben, wo man über eine Policy sagen kann, dass man die Klasse jetzt gerne multi- oder singlethreaded hätte. Ist aber schon wieder ne Weile her, dass ich den gelesen habe, und greifbar habe ich ihn auch gerade nicht.</p>
<p>Wer hilft meinem Gedächtnis mal kurz auf die Sprünge?</p>
<p>Philipp</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/275909/policy-benutzen-um-threading-verhalten-in-klasse-zu-geben</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 16:15:59 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/275909.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 23 Oct 2010 00:37:19 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 00:37:19 GMT]]></title><description><![CDATA[<p>Wo ich gerade schonmal beim Refaktoren bin <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="😉"
    /> würde ich gerne folgendes häßliche Konstrukt eliminieren:</p>
<pre><code class="language-cpp">class Foo {
public:
    void bar() {
#ifdef THREADING_MULTI
        boost::mutex::scoped_lock lock(mutex_);
#endif
        doSomething;
    }
private:
#ifdef THREADING_MULTI
    boost::mutex mutex_;
#endif
};
</code></pre>
<p>Ich erinnere mich dunkel, im Alexandrescu genau so ein Beispiel gelesen zu haben, wo man über eine Policy sagen kann, dass man die Klasse jetzt gerne multi- oder singlethreaded hätte. Ist aber schon wieder ne Weile her, dass ich den gelesen habe, und greifbar habe ich ihn auch gerade nicht.</p>
<p>Wer hilft meinem Gedächtnis mal kurz auf die Sprünge?</p>
<p>Philipp</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969339</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969339</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 00:37:19 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 06:50:35 GMT]]></title><description><![CDATA[<p>Mach ein Template Argument, welches die ThreadingPolicy ist.<br />
Im fall von Multi Threaded sind dort z.B. Methoden drin mit lock(..) / unlock(..) etc. Im Fall von Single Threaded sind dort die impl. einfach leer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969356</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969356</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Sat, 23 Oct 2010 06:50:35 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 12:29:48 GMT]]></title><description><![CDATA[<p>Hab da mal was gebastelt.</p>
<p>Folgendes ist aber Quark, weil scoped_lock natürlich nicht funktioniert. Den RAII-Komfort von scoped_lock will ich aber nicht verlieren. Wie bringe ich das in der Policy unter?</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
using namespace std;

class BoostThreader {
public:
    typedef boost::mutex Mutex;
    void lock(Mutex&amp; the_lock) {
        boost::mutex::scoped_lock scoped_lock(the_lock);
    }
};

class SingleThreaded {
public:
    typedef void* Mutex;
    void lock(Mutex&amp;) {}
};

template &lt;class ThreadingPolicy&gt;
class Foo: public ThreadingPolicy {
public:
    typedef typename ThreadingPolicy::Mutex Mutex;
    using ThreadingPolicy::lock;
    void bar() {
        lock(lock_);
        cout &lt;&lt; &quot;Bar!&quot; &lt;&lt; endl;
    }
private:
    Mutex lock_;
};

int main(int argc, char *argv[])
{
    Foo&lt;BoostThreader&gt; my_threaded_foo;
    my_threaded_foo.bar();

    Foo&lt;SingleThreaded&gt; my_singlethreaded_foo;
    my_singlethreaded_foo.bar();

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1969462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969462</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 12:29:48 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 12:47:51 GMT]]></title><description><![CDATA[<p>Wieso erbst du von der Policy? Und wieso überhaupt so kompliziert? <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="🙂"
    /><br />
Grundsätzlich musst du nur eine neue Mutex-Klasse erstellen, welche das Lockable Konzept von Boost unterstützt, aber tatsächlich nichts tut:</p>
<pre><code class="language-cpp">struct no_mutex
{
  void lock() { }
  void unlock() { }
  bool try_lock() { return true; }
};
</code></pre>
<p>Und nun zu deiner Foo-Klasse:</p>
<pre><code class="language-cpp">template&lt;typename ThreadingMutexT&gt;
class Foo
{
private:
  ThreadingMutexT m_mutex;

public:
  void bar()
  {
    boost::lock_guard&lt;ThreadingMutexT&gt; guard(m_mutex);
  }
};
</code></pre>
<p>Und das ganze in der Anwendung:</p>
<pre><code class="language-cpp">int main()
{
  Foo&lt;boost::mutex&gt; mutex_foo;
  Foo&lt;no_mutex&gt; no_mutex_foo;

  mutex_foo.bar();
  no_mutex_foo.bar();

  return 0;
}
</code></pre>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969472</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969472</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 23 Oct 2010 12:47:51 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 12:50:29 GMT]]></title><description><![CDATA[<p>Das Problem ist, dass ich boost komplett wegkapseln muss, da der single-threaded teil des projekts kein boost zur verfügung hat.</p>
<p>Daher darf in der Klasse kein boost-Code drinstehen, der muß über die Policy reinkommen. Das ging vorher halt über ein #ifdef.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969474</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969474</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 12:50:29 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 13:08:51 GMT]]></title><description><![CDATA[<p>Dann schreib halt eben deinen eigenen Lock-Guard. Ist ja auch nicht weiters wild:</p>
<pre><code class="language-cpp">template&lt;typename MutexT&gt;
class scoped_lock
{
private:
  MutexT&amp; m_mutex;

public:
  scoped_lock(Mutex&amp; mutex)
   : m_mutex(mutex)
  {
    m_mutex.lock();
  }

  ~scoped_lock()
  {
    m_mutex.unlock();
  }

private:
  scoped_lock(scoped_lock const&amp;) { }
  scoped_lock&amp; operator =(scoped_lock const&amp;) { }
};
</code></pre>
<p>Statt <code>boost::lock_guard</code> verwendest du halt nun <code>scoped_lock</code> .</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969481</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969481</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 23 Oct 2010 13:08:51 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 13:30:05 GMT]]></title><description><![CDATA[<p>Das scheint genau das zu leisten, was ich brauche:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;QMutexLocker&gt;
using namespace std;

class BoostThreaded {
public:
    typedef boost::mutex Mutex;
    typedef boost::mutex::scoped_lock ScopedLock;
protected:
    Mutex lock_;
};

class QThreaded {
public:
    typedef QMutex Mutex;
    typedef QMutexLocker ScopedLock;
    QThreaded():lock_(new QMutex) {};
    ~QThreaded() { delete lock_; }
protected:
    Mutex* lock_;
};

class SingleThreaded {
public:
    typedef void* Mutex;
    typedef void* ScopedLock;
protected:
    Mutex lock_;
};

template &lt;class ThreadingPolicy&gt;
class Foo: public ThreadingPolicy {
public:
    typedef typename ThreadingPolicy::ScopedLock ScopedLock;
    using ThreadingPolicy::lock_;
    void bar() {
        ScopedLock lock(lock_);
        cout &lt;&lt; &quot;Bar!&quot; &lt;&lt; endl;
    }
};

int main(int argc, char *argv[])
{
    Foo&lt;BoostThreaded&gt; my_threaded_foo;
    my_threaded_foo.bar();

    Foo&lt;QThreaded&gt; my_qthreaded_foo;
    my_qthreaded_foo.bar();

    Foo&lt;SingleThreaded&gt; my_singlethreaded_foo;
    my_singlethreaded_foo.bar();

    return 0;
}
</code></pre>
<p>Meinungen ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969500</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969500</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 13:30:05 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 13:34:32 GMT]]></title><description><![CDATA[<p>Wieso erbst du von der Policy?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969503</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969503</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 23 Oct 2010 13:34:32 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 13:40:49 GMT]]></title><description><![CDATA[<p>Ähm, weil ich das so gelernt habe?!<br />
Laut Alexandrescu ist policy-based design die Kombination von Mehrfachvererbung mit Templates durch das Erben von seinen Templateparametern. Wikipedia sieht das genauso.</p>
<p>Philipp</p>
<p>EDIT: Und so klappts auch mit der Nachbarin, ähh, der Wait-Condition:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;QMutexLocker&gt;
#include &lt;QWaitCondition&gt;
using namespace std;

class BoostThreaded {
public:
    typedef boost::mutex Mutex;
    typedef boost::mutex::scoped_lock ScopedLock;
    typedef boost::condition_variable WaitCondition;
    void wait(ScopedLock&amp; lock) { condition_.wait(lock); }
    void notify() { condition_.notify_one(); }
protected:
    Mutex lock_;
    WaitCondition condition_;
};

class QThreaded {
public:
    typedef QMutex Mutex;
    typedef QMutexLocker ScopedLock;
    typedef QWaitCondition WaitCondition;
    void wait(ScopedLock&amp;) { condition_.wait(lock_); }
    void notify() { condition_.wakeOne(); }
    QThreaded():lock_(new QMutex) {};
    ~QThreaded() { delete lock_; }
protected:
    Mutex* lock_;
    WaitCondition condition_;
};

class SingleThreaded {
public:
    typedef void* Mutex;
    typedef void* ScopedLock;
    void wait(ScopedLock&amp;) {}
    void notify() {}
protected:
    Mutex lock_;
};

template &lt;class ThreadingPolicy&gt;
class Foo: public ThreadingPolicy {
public:
    typedef typename ThreadingPolicy::ScopedLock ScopedLock;
    using ThreadingPolicy::lock_;
    using ThreadingPolicy::wait;
    using ThreadingPolicy::notify;
    void bar() {
        ScopedLock lock(lock_);
        cout &lt;&lt; &quot;Bar!&quot; &lt;&lt; endl;
        wait(lock);
        notify();
    }
};

int main(int argc, char *argv[])
{
    Foo&lt;BoostThreaded&gt; my_threaded_foo;
    my_threaded_foo.bar();

    Foo&lt;QThreaded&gt; my_qthreaded_foo;
    my_qthreaded_foo.bar();

    Foo&lt;SingleThreaded&gt; my_singlethreaded_foo;
    my_singlethreaded_foo.bar();

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1969504</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969504</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 13:40:49 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 13:54:20 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Wieso erbst du von der Policy?</p>
</blockquote>
<p>Erben muß nicht sein, und eigentlich denke ich, daß es hier böse ist.<br />
Aber die &quot;Empty Member&quot; Optimization <a href="http://www.cantrip.org/emptyopt.html" rel="nofollow">http://www.cantrip.org/emptyopt.html</a> greift da so schön.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969515</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969515</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 23 Oct 2010 13:54:20 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 14:07:11 GMT]]></title><description><![CDATA[<p>Aber wie soll ich sonst an die mutex-membervariable drankommen? Dann müsste ich ja Foo zum friend jeder Policy machen, bzw die Policy selbst wieder zum template, damit T ihr friend sein kann, damit er auf mutex_ zugreifen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969523</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969523</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 14:07:11 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 14:11:32 GMT]]></title><description><![CDATA[<p>PhilippM schrieb:</p>
<blockquote>
<p>Aber wie soll ich sonst an die mutex-membervariable drankommen? Dann müsste ich ja Foo zum friend jeder Policy machen, bzw die Policy selbst wieder zum template, damit T ihr friend sein kann, damit er auf mutex_ zugreifen kann.</p>
</blockquote>
<p>Policies sind so klein und simpel, da dard ein Attribut auch mal pubnlic sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1969527</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969527</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 23 Oct 2010 14:11:32 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 14:12:34 GMT]]></title><description><![CDATA[<p>na dann <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1969528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969528</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 14:12:34 GMT</pubDate></item><item><title><![CDATA[Reply to Policy benutzen, um Threading-Verhalten in Klasse zu geben on Sat, 23 Oct 2010 14:16:26 GMT]]></title><description><![CDATA[<p>Dann präsentiere ich hier die parametrierbare concurrent-queue:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;queue&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;QMutexLocker&gt;
#include &lt;QWaitCondition&gt;
using namespace std;

class BoostThreaded {
public:
    typedef boost::mutex Mutex;
    typedef boost::mutex::scoped_lock ScopedLock;
    typedef boost::condition_variable WaitCondition;
    void wait(ScopedLock&amp; lock) { condition_.wait(lock); }
    void notify() { condition_.notify_one(); }
    Mutex mutex_;
    WaitCondition condition_;
};

class QThreaded {
public:
    typedef QMutex Mutex;
    typedef QMutexLocker ScopedLock;
    typedef QWaitCondition WaitCondition;
    void wait(ScopedLock&amp;) { condition_.wait(mutex_); }
    void notify() { condition_.wakeOne(); }
    QThreaded():mutex_(new QMutex) {};
    ~QThreaded() { delete mutex_; }
    Mutex* mutex_;
    WaitCondition condition_;
};

class SingleThreaded {
public:
    typedef void* Mutex;
    typedef void* ScopedLock;
    void wait(ScopedLock&amp;) {}
    void notify() {}
    Mutex mutex_;
};

template &lt;class ThreadingPolicy&gt;
class Foo {
public:
    typedef typename ThreadingPolicy::ScopedLock ScopedLock;

    void bar() {
        ScopedLock lock(tp.mutex_);
        cout &lt;&lt; &quot;Bar!&quot; &lt;&lt; endl;
    }
private:
    ThreadingPolicy tp;
};

template&lt;typename Data, class ThreadingPolicy&gt;
class concurrent_queue
{
public:
    void push(Data const&amp; data)
    {
        {
            ScopedLock lock(tp.mutex_);
            the_queue.push(data);
        }
        tp.notify();
    }

    bool empty() const
    {
        ScopedLock lock(tp.mutex_);
        return the_queue.empty();
    }

    bool try_pop(Data&amp; popped_value)
    {
        ScopedLock lock(tp.mutex_);
        if(the_queue.empty())
        {
            return false;
        }

        popped_value = the_queue.front();
        the_queue.pop();
        return true;
    }

    void wait_and_pop(Data&amp; popped_value)
    {
        ScopedLock lock(tp.mutex_);
        while(the_queue.empty())
        {
            wait(mutex_);
        }

        popped_value=the_queue.front();
        the_queue.pop();
    }
private:
    typedef typename ThreadingPolicy::ScopedLock ScopedLock;
    std::queue&lt;Data&gt; the_queue;
    ThreadingPolicy tp;
};

int main(int, char **)
{
    Foo&lt;BoostThreaded&gt; my_threaded_foo;
    my_threaded_foo.bar();

    Foo&lt;QThreaded&gt; my_qthreaded_foo;
    my_qthreaded_foo.bar();

    Foo&lt;SingleThreaded&gt; my_singlethreaded_foo;
    my_singlethreaded_foo.bar();

    concurrent_queue&lt;float, BoostThreaded&gt; my_concurrent_float_queue;
    my_concurrent_float_queue.push(23.42f);

    float f;
    my_concurrent_float_queue.wait_and_pop(f);
    cout &lt;&lt; f &lt;&lt; endl;

    return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1969531</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1969531</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Sat, 23 Oct 2010 14:16:26 GMT</pubDate></item></channel></rss>