???? 2-1 条件变量
- ???? 当⼀个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。
- ???? 例如⼀个线程访问队列时,发现队列为空,它只能等待,只到其它线程将⼀个节点添加到队列中。这种情况就需要⽤到条件变量。
???? 2-2 同步概念与竞态条件
-
同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从⽽有效避免饥饿问题,叫做同步。
-
竞态条件:因为时序问题,⽽导致程序异常,我们称之为竞态条件。在线程场景下,这种问题也不难理解
???? 2-3 条件变量函数
???? 初始化
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t
*restrict attr);
参数:
cond:要初始化的条件变量
attr:NULL
???? 销毁
int pthread_cond_destroy(pthread_cond_t *cond)
???? 等待条件满⾜
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict
mutex);
参数:
cond:要在这个条件变量上等待
mutex:互斥量,后⾯详细解释
???? 唤醒等待
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
简单案例:
- 我们先使⽤ PTHREAD_COND / MUTEX_INITIALIZER 进⾏测试,对其他细节暂不追究
- 然后将接⼝更改成为使⽤ pthread_cond_init / pthread_cond_destroy 的⽅式,⽅便后续进⾏封装
#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *active(void *args)
{
std::string name = static_cast<const char*>(args);
while(true)
{
pthread_mutex_lock(&mutex);
// 没有对资源是否就绪的判定
pthread_cond_wait(&cond, &mutex);
printf("%s is active!\n", name.c_str());
pthread_mutex_unlock(&mutex);
}
return nullptr;
}
int main()
{
pthread_t tid1, tid2, tid3;
pthread_create(&tid1, nullptr, active, (void*)"thread-1");
pthread_create(&tid1, nullptr, active, (void*)"thread-2");
pthread_create(&tid1, nullptr, active, (void*)"thread-3");
sleep(1);
printf("Main thread ctrl begin...\n");
while(true)
{
printf("main wakeup thread...\n");
pthread_cond_signal(&cond);
sleep(1);
}
pthread_join(tid1, nullptr);
pthread_join(tid2, nullptr);
pthread_join(tid3, nullptr);
return 0;
}
????运行结果:
Main thread ctrl begin...
main wakeup thread...
thread-1 is active!
main wakeup thread...
thread-2 is active!
main wakeup thread...
thread-3 is active!