C++ 多线程:条件变量

c++ multithreading: condition variable

本文关键字:变量 条件 多线程 C++      更新时间:2023-10-16

我是多线程的新手。这就是我想要的

thread_function(){
    // do job1;
    //wait main thread to notify;
    // do job2;
}
main(){
   //create two threads
   //wait both threads to finish job1
   //finish job3, then let both threads start job2
   //wait both threads to join
}

最好的方法是什么?谢谢。

这是我的代码

void job1(){
}
void job2(){
}
void job3(){
}
int main(){
  thread t11(job1);
  thread t12(job1);
  t11.join();
  t12.join();
  job3();
  thread t21(job2);
  thread t22(job2);
  t21.join();
  t22.join();
}

我的问题是我是否可以将 job1 和 job2 组合到一个函数中,并使用条件变量来控制顺序?

我会给你一个示例(类似于生产者-消费者问题)这不是您正在寻找的确切解决方案,但下面的代码将指导您,

下面的 "q" 受互斥锁保护,条件变量等待它收到通知或 !q.empty(虚假唤醒需要)或超时。

std::condition_variable cond;
std::deque<int> q;
std::mutex mu;
void function_1() {
    int count = 50;
    while (count > 0)
    {
        // Condition variables when used lock should be unique_lock
        // lock the resource
        std::unique_lock<mutex> locker(mu);
        // defer the lock until further 
        //std::unique_lock<mutex> locker(mu, std::defer_lock);
        q.push_front(count);
        locker.unlock();
        //cond.notify_one();
        cond.notify_all();
        //std::this_thread::sleep_for(chrono::seconds(1));
        count--;
    }
}
void function_2(int x,int y) {
    int data = 0;
    while (data != 1)
    {
        // mu is the common mutex this resource is protected for the q.
        std::unique_lock<mutex> locker(mu);
        // this will only be done when !q.empty()
        // This will make sure it is handled by multiple threads
        auto now = std::chrono::system_clock::now();
        if (cond.wait_until(locker, now + y * 100ms, []() { return !q.empty(); }))
        {
            auto nowx = std::chrono::system_clock::now();
            cout << "Thread " << x << "waited for " << (nowx-now).count() << endl;
        }
        else
        {
            cout << "Timed out " << endl;
            break;
        }
        data = q.back();
        q.pop_back();
        locker.unlock();
        cout << x << " got value from t1 " << data << endl;
    }
}
int main()
{
     std::thread t1(function_1);
     std::thread t2(function_2,1,50);
     std::thread t3(function_2,2,60);
     std::thread t4(function_2,3,100);
     t1.join();
     t2.join();
     t3.join();
     t4.join();
     return 0;
}