条件变量实现线程同步

(1) 什么是条件变量实现线程同步?
  假如我们的程序中有两个线程,一个是生产者线程,另一个是消费者线程,生产者线程每隔一段时间把数据写入到缓冲区buffer中,而消费者线程则每隔一段时间从buffer中取出数据,为了避免两个线程读写混乱,我们让生产线线程写完后再通知消费者来读数据,那么则可以用条件变量来实现线程的同步。

(2) 条件变量的两个动作
  条件不满足: 阻塞线程
  条件满足: 通知阻塞的线程开始工作

(3) 条件变量的类型:

pthread_cond_t cond;

(4) 主要函数:
初始化一个条件变量( 第二参数一般为NULL)

int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

销毁一个条件变量

int pthread_cond_destroy(pthread_cond_t *cond);

阻塞等待一个条件变量

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

       阻塞线程
       将已经上锁的mutex解锁
       解除阻塞后会对mutex加锁

限时等待一个条件变量

int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个。

int pthread_cond_signal(pthread_cond_t *cond);

唤醒全部阻塞在条件变量上的线程

int pthread_cond_broadcast(pthread_cond_t *cond);

(5)注意事项

注意 1:
mutex 互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP)。
在调用 pthread_cond_wait()前必须由本线程加锁 pthread_mutex_lock()。
在更新条件等待队列以前,mutex 保持锁定状态。
在线程挂起进入等待前解锁。
注意 2:
在条件满足从而离开 pthread_cond_wait() 之前,mutex 将被重新加锁,以与进入
pthread_cond_wait()前的加锁动作对应。
也就是说在做 pthread_cond_wait 之前,往往要用 pthread_mutex_lock 进行加锁,而
调 pthread_cond_wait 函 数 会 将 锁 解 开 , 然 后 将 线 程 挂 起 阻 塞 。 直 到 条 件 被
pthread_cond_signal 激发,该函数内部又会将锁状态恢复为锁定状态,
最后再用
pthread_mutex_unlock 进行解锁。

注意 3:
pthread_cond_wait() 和 pthread_cond_timedwait()都被实现为取消点,也就是说如果
pthread_cond_wait()被取消,则退出阻塞,然后将锁状态恢复,然后当前线程就会终止。即
互斥锁又恢复锁定状态,然而当前线程已经被取消掉,那么这个互斥锁就不会被解开了,此
时锁得不到释放,就会造成死锁,因而需要在线程退出前为其解锁。

(5)示例

1.初始化条件变量和互斥锁
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

2.在线程中使用
(1)生产者线程
    pthread_mutex_lock(&mutex);// 使用互斥锁保护共享数据

    对缓冲区buffer写入操作
    
    pthread_cond_signal(&cond);// 通知阻塞的消费者线程,数据写入完毕,可以解除阻塞了
    pthread_mutex_unlock(&mutex);

(2)消费者线程
    pthread_mutex_lock(&mutex);  //调用pthread_cond_wait前一般都会搭配pthread_mutex_lock
    pthread_cond_wait(&cond, &mutex);    //等待生产者线程的通知
    从缓冲区buffer中读出数据
    pthread_mutex_unlock(&mutex);        //解锁

3.销毁条件变量和互斥锁
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

本文参考文章:

https://www.cnblogs.com/hesper/p/10738996.html

https://www.cnblogs.com/harlanc/p/8596211.html

发布了42 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37659294/article/details/104273874