我做了一个简单的实验来测试:
代码:
#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;
}
但事实上,子线程将立即打印“主线程休眠3秒后”。我哪里弄错了?
感谢。
答案 0 :(得分:4)
最重要的是,由于您将C ++标记附加到此问题,因此请使用C ++线程功能,而不是pthread库。您不能保证始终可以访问它(例如在Windows上),而std::thread
被设计为跨平台并且没有使用pthread()
库的C接口带来的一些烦恼< / p>
其次,初始化你的变量,C和C API很烦人。第三,你需要考虑虚假的唤醒,在条件变量等待时放一个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();
}
答案 1 :(得分:1)
我不了解Linux线程功能,但在Windows中,您必须初始化与Linux中pthread_cond_t cond
对应的变量。
有一个名为pthread_cond_init
的函数的联机帮助页似乎就是这样。