Note that there are some explanatory texts on larger screens.

plurals
  1. POfine-grained locking queue in c++
    text
    copied!<p>Here's a fine-grained locking queue introduced by Anthony Williams in chapter 6.2.3 C++ Concurrency in Action.</p> <pre><code>/* pop only need lock head_mutex and a small section of tail_mutex,push only need tail_mutex mutex.maximum container concurrency. */ template&lt;typename T&gt; class threadsafe_queue { private: struct node { std::shared_ptr&lt;T&gt; data; std::unique_ptr&lt;node&gt; next; } std::mutex head_mutex; //when change the head lock it. std::unique_ptr&lt;node&gt; head; std::mutex tail_mutex; //when change the tail lock it. node* tail; std::condition_variable data_cond; node* get_tail() { std::lock_guard&lt;std::mutex&gt; tail_lock(tail_mutex); return tail; } public: /* create a dummy node */ threadsafe_queue(): head(new node),tail(head.get()) {} std::shared_ptr&lt;T&gt; wait_and_pop() { std::unique_lock&lt;std::mutex&gt; head_lock; data_cond.wait(head_lock,[&amp;]{return head.get()!=get_tail();}); //#1 std::unique_ptr&lt;node&gt; old_head=std::move(head); head=std::move(old_head-&gt;next); return old_head; } void push(T new_value) { std::shared_ptr&lt;T&gt; new_data( std::make_shared&lt;T&gt;(std::move(new_value))); std::unique_ptr&lt;node&gt; p(new node); { std::lock_guard&lt;std::mutex&gt; tail_lock(tail_mutex); tail-&gt;data=new_data; node* const new_tail=p.get(); tail-&gt;next=std::move(p); tail=new_tail; } data_cond.notify_one(); } } </code></pre> <p>Here's the situation: There are two threads (<code>thread1</code> and <code>thread2</code>). <code>thread1</code> is doing a <code>wait_and_pop</code> and <code>thread2</code> is doing a <code>push</code>. The queue is empty.</p> <p><code>thread1</code> is in #2, had already checked <code>head.get()!=get_tail()</code> before <code>data_cond.wait()</code>. At this time its CPU period had run out. <code>thread2</code> begins.</p> <p><code>thread2</code> finished the <code>push</code> function and did <code>data_cond.notify_one()</code>. <code>thread1</code> begins again.</p> <p>Now <code>thread1</code> begins <code>data_cond.wait()</code>, but it waits forever.</p> <p>Would this situation possibly happen ?If so, how to get this container fixed ?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload