简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
本篇目的: 理解pthread_cond_wait与pthread_cond_timedwait用法区别
函数 | 区别 |
---|---|
pthread_cond_wait |
与pthread_cond_signal函数成对出现,如果没有pthread_cond_signal给它发信号,它死等,等到天荒地老… |
pthread_cond_timedwait |
自己设置超时时间,一旦超过设定时间,自动执行pthread_cond_timedwait函数后边的代码。如果pthread_cond_signal在pthread_cond_timedwait 设置超时时间之前给它发信号,它会收到信号,提前结束等待。 |
pthread_cond_signal |
一次只能唤醒一个等待中的线程 |
pthread_cond_broadcast |
可以唤醒全部等待中的线程 |
pthread_mutex_t |
Linux中用于互斥锁的结构体类型。互斥锁用于保护临界区,确保同时只有一个线程可以访问共享资源。 |
pthread_cond_t |
在Linux中,pthread_cond_t是用于线程间同步的条件变量。条件变量用于在线程之间传递信号,帮助线程进行等待和唤醒操作。条件变量通常与互斥锁(pthread_mutex_t)一起使用。当某个线程需要等待某个条件满足时,它会调用pthread_cond_wait函数将自己阻塞,并释放占有的互斥锁。当另一个线程满足了条件并调用了pthread_cond_signal或pthread_cond_broadcast函数发送信号时,等待的线程会被唤醒并重新获取互斥锁,从而继续执行。 |
#include
#include
#include
#include
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main() {
std::thread thread = std::thread([&]() {
cout << "线程等待信号到来..." << endl;
pthread_mutex_lock(&mutex);
//1.如果不调用pthread_cond_signal(&cond)函数发信号,永远死等.
pthread_cond_wait(&cond, &mutex);
cout << "Thread timed wait for 10s." << endl;
pthread_mutex_unlock(&mutex);
});
//1.给pthread_cond_wait和pthread_cond_timedwait发信号(它俩是成对出现的),使其后边的代码可以执行.
sleep(1);
pthread_cond_signal(&cond);//仅可以唤醒一个线程
sleep(2);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
thread.join();
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main() {
//1.给pthread_cond_wait和pthread_cond_timedwait发信号(它俩是成对出现的),使其后边的代码可以执行.
std::thread thread = std::thread([&]() {
cout << "线程等待信号到来..." << endl;
struct timeval now;
struct timespec outtime;
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 10;//如果没有等到信号,则超过10s后自动处理.
outtime.tv_nsec = now.tv_usec * 1000;
pthread_mutex_lock(&mutex);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
//2.可以设置超时时间,一旦超过设定时间,自动执行pthread_cond_timedwait函数后边的代码,它不受pthread_cond_signal的影响.
pthread_cond_timedwait(&cond, &mutex, &outtime);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
cout << "Thread timed wait for 10s." << endl;
pthread_mutex_unlock(&mutex);
});
sleep(1);
pthread_cond_signal(&cond);//仅可以唤醒一个线程
sleep(2);
thread.join();
return 0;
}
#include
#include
#include
#include
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main() {
std::thread thread = std::thread([&]() {
cout << "线程等待信号到来..." << endl;
pthread_mutex_lock(&mutex);
//1.如果不调用pthread_cond_signal(&cond)函数发信号,永远死等.
pthread_cond_wait(&cond, &mutex);
cout << "Thread timed wait for 10s." << endl;
pthread_mutex_unlock(&mutex);
});
//1.给pthread_cond_wait和pthread_cond_timedwait发信号(它俩是成对出现的),使其后边的代码可以执行.
sleep(1);
pthread_cond_broadcast(&cond);//可以唤醒全部线程
sleep(2);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
thread.join();
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main() {
//1.给pthread_cond_wait和pthread_cond_timedwait发信号(它俩是成对出现的),使其后边的代码可以执行.
std::thread thread = std::thread([&]() {
cout << "线程等待信号到来..." << endl;
struct timeval now;
struct timespec outtime;
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 10;//如果没有等到信号,则超过10s后自动处理.
outtime.tv_nsec = now.tv_usec * 1000;
pthread_mutex_lock(&mutex);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
//2.可以设置超时时间,一旦超过设定时间,自动执行pthread_cond_timedwait函数后边的代码,它不受pthread_cond_signal的影响.
pthread_cond_timedwait(&cond, &mutex, &outtime);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
cout << "Thread timed wait for 10s." << endl;
pthread_mutex_unlock(&mutex);
});
sleep(1);
pthread_cond_broadcast(&cond);//可以唤醒全部线程
sleep(2);
thread.join();
return 0;
}
pthread_cond_signal和pthread_cond_wait用法
#include
#include
#include
#include
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main() {
std::thread thread = std::thread([&]() {
cout << "线程等待信号到来..." << endl;
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
pthread_mutex_lock(&mutex);
//1.如果不调用pthread_cond_signal(&cond)函数发信号,永远死等.
pthread_cond_wait(&cond, &mutex);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
cout << "Thread timed wait for 10s." << endl;
pthread_mutex_unlock(&mutex);
});
//1.给pthread_cond_wait和pthread_cond_timedwait发信号(它俩是成对出现的),使其后边的代码可以执行.
sleep(1);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*(reinterpret_cast<int*>(&(cond.__data))));
printf("%s() [%d], cond.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__size))));
printf("%s() [%d], cond.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__align))));
printf("%s() [%d], mutex.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__data))));
printf("%s() [%d], mutex.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__size))));
printf("%s() [%d], mutex.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__align))));
//pthread_cond_signal(&cond);//仅可以唤醒一个线程
pthread_cond_broadcast(&cond);//可以唤醒全部线程
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
printf("%s() [%d], cond.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__size))));
printf("%s() [%d], cond.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__align))));
printf("%s() [%d], mutex.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__data))));
printf("%s() [%d], mutex.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__size))));
printf("%s() [%d], mutex.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__align))));
sleep(2);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
thread.join();
return 0;
}
打印:
线程等待信号到来...
operator()() [16], cond.__data = 0
main() [27], cond.__data = 2
main() [28], cond.__data = 2
main() [30], cond.__size = 2
main() [31], cond.__align = 2
main() [33], mutex.__data = 0
main() [34], mutex.__size = 0
main() [35], mutex.__align = 0
main() [40], cond.__data = 3
main() [41], cond.__size = 3
main() [42], cond.__align = 3
main() [44], mutex.__data = 0
main() [45], mutex.__size = 0
main() [46], mutex.__align = 0
operator()() [20], cond.__data = 3
Thread timed wait for 10s.
main() [49], cond.__data = 3
总结:
在进入线程后,信号没来到之前 cond.__data=0;
当进入main进程时,cond.__data=2;
当pthread_cond_signal(&cond)发送信号后,cond.__data=3,然后线程中的pthread_cond_wait(&cond, &mutex)收到cond.__data=3的信号,
立即释放互斥锁,解除阻塞,程序向下运行,到main函数结束。
pthread_cond_signal和pthread_cond_timedwait用法
#include
#include
#include
#include
#include
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main() {
//1.给pthread_cond_wait和pthread_cond_timedwait发信号(它俩是成对出现的),使其后边的代码可以执行.
std::thread thread = std::thread([&]() {
cout << "线程等待信号到来..." << endl;
struct timeval now;
struct timespec outtime;
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 10;//如果没有等到信号,则超过10s后自动处理.
outtime.tv_nsec = now.tv_usec * 1000;
pthread_mutex_lock(&mutex);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
//2.可以设置超时时间,一旦超过设定时间,自动执行pthread_cond_timedwait函数后边的代码,它不受pthread_cond_signal的影响.
pthread_cond_timedwait(&cond, &mutex, &outtime);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
cout << "Thread timed wait for 10s." << endl;
pthread_mutex_unlock(&mutex);
});
sleep(1);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*(reinterpret_cast<int*>(&(cond.__data))));
printf("%s() [%d], cond.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__size))));
printf("%s() [%d], cond.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__align))));
printf("%s() [%d], mutex.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__data))));
printf("%s() [%d], mutex.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__size))));
printf("%s() [%d], mutex.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__align))));
//pthread_cond_signal(&cond);//仅可以唤醒一个线程
pthread_cond_broadcast(&cond);//可以唤醒全部线程
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
printf("%s() [%d], cond.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__size))));
printf("%s() [%d], cond.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__align))));
printf("%s() [%d], mutex.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__data))));
printf("%s() [%d], mutex.__size = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__size))));
printf("%s() [%d], mutex.__align = %d\n",__FUNCTION__,__LINE__,*((int*)(&(mutex.__align))));
sleep(2);
printf("%s() [%d], cond.__data = %d\n",__FUNCTION__,__LINE__,*((int*)(&(cond.__data))));
thread.join();
return 0;
}
打印
线程等待信号到来...
operator()() [23], cond.__data = 0
main() [33], cond.__data = 2
main() [34], cond.__data = 2
main() [37], cond.__size = 2
main() [38], cond.__align = 2
main() [40], mutex.__data = 0
main() [41], mutex.__size = 0
main() [42], mutex.__align = 0
main() [46], cond.__data = 3
main() [47], cond.__size = 3
main() [48], cond.__align = 3
main() [50], mutex.__data = 0
main() [51], mutex.__size = 0
main() [52], mutex.__align = 0
operator()() [26], cond.__data = 3
Thread timed wait for 10s.
main() [55], cond.__data = 3
总结:
在进入线程后,信号没来到之前 cond.__data=0;
当进入main进程时,cond.__data=2;
当pthread_cond_signal(&cond)发送信号后,cond.__data=3,然后线程中的pthread_cond_wait(&cond, &mutex)收到cond.__data=3的信号,
立即释放互斥锁,解除阻塞,程序向下运行,到main函数结束。
所以不管是pthread_cond_signal、pthread_cond_broadcast发送信号给pthread_cond_wait,还是pthread_cond_timedwait,最终信号发生变化的pthread_cond_t是的结构体变量__data字段,是它发生的变化,解除线程的阻塞状态。