Haruyuki Mohri

毛利春幸のブログです。

std::condition_variableを試した。

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.
f:id:mojeld:20170810153702p:plain
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.

struct turn_thread
{
    std::mutex f_mtx_;
    std::condition_variable f_cond_;
    std::vector<String> f_strings_;
    void processing_from_standby(int process_num)
    {
        std::unique_lock<std::mutex> ulk(f_mtx_);
        //After waiting, execute processing.
        f_cond_.wait(ulk);
        f_strings_.push_back(TimeToStr(Now()) + " process_num=" + IntToStr(process_num));
        //1 second sleep.
        std::this_thread::sleep_for(std::chrono::seconds(1));
        //Only one of the waiting threads is executed.
        f_cond_.notify_one();
    }
    inline void start_and_join(std::vector<std::thread>& vthreads1)
    {
        f_cond_.notify_one();
        for (auto& th:vthreads1)
        {
            th.join();
        }
    }
};

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.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TDateTime dt1{Now()};
    std::vector<std::thread> vthreads1;
    turn_thread turn1;
    for (int i = 0; i < 10; i++)
    {
        vthreads1.push_back(std::thread([i, &turn1](){
                turn1.processing_from_standby(i);
            }));
    }

    turn1.start_and_join(vthreads1);

    for (auto& str1: turn1.f_strings_)
    {
        Memo1->Lines->Append(str1);
    }
    dt1 = Now() - dt1;
    Memo1->Lines->Append(TimeToStr(dt1));
}
//---------------------------------------------------------------------------

Execution result

Threads are executed in an irregular way one by one.
f:id:mojeld:20170810152905p:plain