【问题标题】:"pthread_cond_wait" didn't wait main thread to sleep, why?“pthread_cond_wait”没有等待主线程休眠,为什么?
【发布时间】:2017-11-28 07:43:44
【问题描述】:

我做了一个简单的实验来测试:

  1. 主线程创建子线程。
  2. 子线程等待主线程向条件变量发出信号。
  3. 主线程休眠 3 秒并发出“cond”信号。然后我希望子线程将从“cond_wait”中唤醒并打印。

代码:

#include <pthread.h>
#include <unistd.h>
#include <cassert>
#include <iostream>

using namespace std;
pthread_mutex_t mt;
pthread_cond_t cond;
pthread_t tid;
void* tf(void*arg){
    pthread_mutex_lock(&mt);
    pthread_cond_wait(&cond, &mt);
    cout<<"After main thread sleeps 3 seconds\n";
    return NULL;
}
int main(){
    assert(0==pthread_mutex_init(&mt,NULL));
    pthread_create(&tid,NULL,tf,NULL);
    sleep(3);
    pthread_cond_signal(&cond);
    pthread_join(tid,NULL);//Is 2nd parameter useful?
    pthread_cond_destroy(&cond);
    return 0;
}

但实际上子线程会一次打印“After main thread sleeps 3 seconds”。我哪里做错了?

谢谢。

【问题讨论】:

  • 知道了,我还没有初始化两个pthread_xxxx_全局变量!刚刚修好了!

标签: c++ linux multithreading variables conditional


【解决方案1】:

我不知道 Linux 线程函数,但在 Windows 中,您必须初始化与 Linux 中的 pthread_cond_t cond 对应的变量。

有一个名为 pthread_cond_init 的函数的手册页似乎正是这样做的。

【讨论】:

    【解决方案2】:

    最重要的是,既然您在这个问题上附加了 C++ 标签,请使用 C++ 线程功能,而不是 pthread 库。不能保证您始终可以访问它(例如在 Windows 上),而 std::thread 被设计为跨平台并且免于使用 pthread() 库的 C 接口带来的一些烦恼

    其次,初始化你的变量,C 和 C API 就是这么烦人。第三,您需要考虑虚假唤醒,在条件变量 wait 周围放置一个 while 循环,并为其附加一个实际条件,例如

    while (not_signalled) {
        pthread_cond_wait(&cond, &mt);
    }
    

    可能发生的情况是你的线程被虚假唤醒然后结束,因为你没有一个 while 循环来防止虚假唤醒


    工作 C++ 代码

    #include <thread>
    #include <iostream>
    #include <chrono>
    
    using std::cout;
    using std::endl;
    
    std::mutex mtx;
    std::condition_variable cv;
    bool has_signalled{false};
    
    void th_function() {
        // acquire the lock
        auto lck = std::unique_lock<std::mutex>{mtx};
    
        // loop to protect against spurious wakeups
        while (!has_signalled) {
            // sleep
            cv.wait(lck);
        }
    
        cout << "Thread has been signalled" << endl;
    }
    
    int main() {
        auto th = std::thread{th_function};
    
        // sleep for 2 seconds
        std::this_thread::sleep_for(std::chrono::seconds(2));
    
        // signal and change the variable
        {
            std::lock_guard<std::mutex> lck{mtx};
            has_signalled = true;
        }
    
        // signal
        cv.notify_one();
    
        th.join();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-04
      • 2015-10-09
      • 2019-11-20
      • 2013-02-20
      • 2011-12-26
      相关资源
      最近更新 更多