Author: h.mohri
std::condition_variable is a class for waiting for thread execution until the condition is satisfied.
Used in combination with std::mutex.
I tried the wait() function in std::condition_variable.
This is combined with std::unique_lock<std::mutex>
.
I thought of the following specifications.
As shown in the figure, create multiple threads.
All threads are in Wait state.
Then let the threads run one by one.
Make mutex and condition_variable management class.
The created thread is waited using condition_variable.
Sleeping for 1 second immediately after passing Wait.
Then execution request is made to the next thread.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="k" style="font-weight:bold;">struct</span> <span class="n">turn_thread</span> <span class="p">{</span> <span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">mutex</span> <span class="n">f_mtx_</span><span class="p">;</span> <span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">condition_variable</span> <span class="n">f_cond_</span><span class="p">;</span> <span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">vector</span><span class="o" style="font-weight:bold;"><</span><span class="n">String</span><span class="o" style="font-weight:bold;">></span> <span class="n">f_strings_</span><span class="p">;</span> <span class="kt" style="color:#445588;font-weight:bold;">void</span> <span class="nf" style="color:#990000;font-weight:bold;">processing_from_standby</span><span class="p">(</span><span class="kt" style="color:#445588;font-weight:bold;">int</span> <span class="n">process_num</span><span class="p">)</span> <span class="p">{</span> <span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">unique_lock</span><span class="o" style="font-weight:bold;"><</span><span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">mutex</span><span class="o" style="font-weight:bold;">></span> <span class="n">ulk</span><span class="p">(</span><span class="n">f_mtx_</span><span class="p">);</span> <span class="c1" style="color:#999988;font-style:italic;">//After waiting, execute processing.</span> <span class="n">f_cond_</span><span class="p">.</span><span class="n">wait</span><span class="p">(</span><span class="n">ulk</span><span class="p">);</span> <span class="n">f_strings_</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">TimeToStr</span><span class="p">(</span><span class="n">Now</span><span class="p">())</span> <span class="o" style="font-weight:bold;">+</span> <span class="s" style="color:#d01040;">" process_num="</span> <span class="o" style="font-weight:bold;">+</span> <span class="n">IntToStr</span><span class="p">(</span><span class="n">process_num</span><span class="p">));</span> <span class="c1" style="color:#999988;font-style:italic;">//1 second sleep.</span> <span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">this_thread</span><span class="o" style="font-weight:bold;">::</span><span class="n">sleep_for</span><span class="p">(</span><span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">chrono</span><span class="o" style="font-weight:bold;">::</span><span class="n">seconds</span><span class="p">(</span><span class="mi" style="color:#009999;">1</span><span class="p">));</span> <span class="c1" style="color:#999988;font-style:italic;">//Only one of the waiting threads is executed.</span> <span class="n">f_cond_</span><span class="p">.</span><span class="n">notify_one</span><span class="p">();</span> <span class="p">}</span> <span class="kr" style="font-weight:bold;">inline</span> <span class="kt" style="color:#445588;font-weight:bold;">void</span> <span class="nf" style="color:#990000;font-weight:bold;">start_and_join</span><span class="p">(</span><span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">vector</span><span class="o" style="font-weight:bold;"><</span><span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="kr" style="font-weight:bold;">thread</span><span class="o" style="font-weight:bold;">>&</span> <span class="n">vthreads1</span><span class="p">)</span> <span class="p">{</span> <span class="n">f_cond_</span><span class="p">.</span><span class="n">notify_one</span><span class="p">();</span> <span class="k" style="font-weight:bold;">for</span> <span class="p">(</span><span class="k" style="font-weight:bold;">auto</span><span class="o" style="font-weight:bold;">&</span> <span class="nl" style="color:#990000;font-weight:bold;">th</span><span class="p">:</span><span class="n">vthreads1</span><span class="p">)</span> <span class="p">{</span> <span class="n">th</span><span class="p">.</span><span class="n">join</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span> |
Thread creation function
It is a button event of C++Builder.
We create 10 threads, but they are all waited.
Thereafter, to perform one single thread start_and_join() function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="kt" style="color:#445588;font-weight:bold;">void</span> <span class="kr" style="font-weight:bold;">__fastcall</span> <span class="n">TForm1</span><span class="o" style="font-weight:bold;">::</span><span class="n">Button1Click</span><span class="p">(</span><span class="n">TObject</span> <span class="o" style="font-weight:bold;">*</span><span class="n">Sender</span><span class="p">)</span> <span class="p">{</span> <span class="c1" style="color:#999988;font-style:italic;">//</span> <span class="n">TDateTime</span> <span class="n">dt1</span><span class="p">{</span><span class="n">Now</span><span class="p">()};</span> <span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="n">vector</span><span class="o" style="font-weight:bold;"><</span><span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="kr" style="font-weight:bold;">thread</span><span class="o" style="font-weight:bold;">></span> <span class="n">vthreads1</span><span class="p">;</span> <span class="n">turn_thread</span> <span class="n">turn1</span><span class="p">;</span> <span class="k" style="font-weight:bold;">for</span> <span class="p">(</span><span class="kt" style="color:#445588;font-weight:bold;">int</span> <span class="n">i</span> <span class="o" style="font-weight:bold;">=</span> <span class="mi" style="color:#009999;">0</span><span class="p">;</span> <span class="n">i</span> <span class="o" style="font-weight:bold;"><</span> <span class="mi" style="color:#009999;">10</span><span class="p">;</span> <span class="n">i</span><span class="o" style="font-weight:bold;">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">vthreads1</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o" style="font-weight:bold;">::</span><span class="kr" style="font-weight:bold;">thread</span><span class="p">([</span><span class="n" style="box-sizing: inherit;">i</span><span class="p" style="box-sizing: inherit;">,</span> <span class="o" style="box-sizing: inherit; font-weight: bold;">&</span><span class="n" style="box-sizing: inherit;">turn1</span><span class="p" style="box-sizing: inherit;">](){</span> <span class="n">turn1</span><span class="p">.</span><span class="n">processing_from_standby</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="p">}));</span> <span class="p">}</span> <span class="n">turn1</span><span class="p">.</span><span class="n">start_and_join</span><span class="p">(</span><span class="n">vthreads1</span><span class="p">);</span> <span class="k" style="font-weight:bold;">for</span> <span class="p">(</span><span class="k" style="font-weight:bold;">auto</span><span class="o" style="font-weight:bold;">&</span> <span class="nl" style="color:#990000;font-weight:bold;">str1</span><span class="p">:</span> <span class="n">turn1</span><span class="p">.</span><span class="n">f_strings_</span><span class="p">)</span> <span class="p">{</span> <span class="n">Memo1</span><span class="o" style="font-weight:bold;">-></span><span class="n">Lines</span><span class="o" style="font-weight:bold;">-></span><span class="n">Append</span><span class="p">(</span><span class="n">str1</span><span class="p">);</span> <span class="p">}</span> <span class="n">dt1</span> <span class="o" style="font-weight:bold;">=</span> <span class="n">Now</span><span class="p">()</span> <span class="o" style="font-weight:bold;">-</span> <span class="n">dt1</span><span class="p">;</span> <span class="n">Memo1</span><span class="o" style="font-weight:bold;">-></span><span class="n">Lines</span><span class="o" style="font-weight:bold;">-></span><span class="n">Append</span><span class="p">(</span><span class="n">TimeToStr</span><span class="p">(</span><span class="n">dt1</span><span class="p">));</span> <span class="p">}</span> <span class="c1" style="color:#999988;font-style:italic;">//---------------------------------------------------------------------------</span> |
Execution result
Threads are executed in an irregular way one by one.
In C++Builder(C++11), use timed_mutex.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition