从C ++ 11中的另一个线程解锁一个线程

时间:2015-05-09 20:50:18

标签: c++ multithreading c++11 concurrency mutex

我在C ++ 11的thread.h api方面没有广泛的知识(实际上我也不熟悉线程编程,但我最近读了很多,知道并发和类似的东西)但我开始使用它,我面临一个我还没有真正遇到过的问题。

我有两个线程函数,比如说这些

std::thread(thread1, args); // Spawn thread 1
std::thread(thread2, args); // Spawn thread 2

[...]

int thread1(bunch of args)
{
     lock_thread_2();
     [do stuff]
     while (some condition) {
         [do stuff]
         unlock_thread_2();
     }
}

int thread2(bunch of args)
{
     while (some condition) {
         [do stuff]
         wait_for_thread1_to_unlock_me();
     }
}

我首先考虑使用std :: mutex进行操作,但我读到它可能很危险,因为如果我解锁已经解锁的互斥锁并且在它之上它不会像mutex一样工作,那么行为是不确定的.lock()并不一定会暂停执行(只有在互斥锁已被锁定的情况下才会执行)因此写入时非常可怕,我必须将unlock()和lock锁定( )一起打电话。

这里需要注意的重要事项是thread2的执行仅由thread1控制,但thread2永远不会以任何方式锁定thread1。只有thread2被thread1锁定,只有thread1控制执行流程thread2,否则不会。

你会如何以一种干净的方式,支持的方式做到这一点?你愿意举一个代码的例子吗?

谢谢!

2 个答案:

答案 0 :(得分:5)

使用condition_variable

std::condition_variable cv;

int thread1(bunch of args)
{
     [do stuff]
     while (some condition) {
         [do stuff]
         cv.notify_one();
     }
}

int thread2(bunch of args)
{
     std::mutex mtx;
     std::unique_lock<std::mutex> lk(mtx);

     while (some condition) {
         [do stuff]
         cv.wait(lk);
     }
}

wait()返回时,cv将被notify() - 编辑...或者会有虚假的唤醒。为了处理后者,添加谓词通常很有帮助。

答案 1 :(得分:2)

您可以使用Array ( [1] => Array ( [patient] => 987 [condition] => xyz ) ) 。它允许您通过使用std::condition_variablenotify_one方法从另一个线程通知线程,以分别恢复等待条件变量的一个或所有线程。在您的代码中,您可以像这样使用它:

notify_all

但要注意,条件变量会偶尔出现虚假唤醒,因此您可能需要循环等待条件以检查唤醒是否有效,如下所示:

std::condition_variable my_var;

void thread1(args) {
    ...
    while(condition1) {
        ...
        my_var.notify_one();
    }
}

void thread2(args) {
    std::mutex mutex;
    std::unique_lock<std::mutex> lock(mutex);
    ...
    while(condition2) {
        ...
        my_var.wait(lock);
    }
}

您可以详细了解do { my_var.wait(lock); } while(!valid_wakeup); here