[多线程] pthread_cond_signal()和pthread_cond_wait()用法解析

3 篇文章 0 订阅
2 篇文章 1 订阅
pthread_mutex_t count_lock;  //互斥量
pthread_cond_t count_nonzero;  //条件变量
unsigned count;

/* 线程1 */
decrement_count()
{
    pthread_mutex_lock(&count_lock);
    while (count == 0)
    {
        pthread_cond_wait(&count_nonzero, &count_lock);
    }
    count = count - 1;
    pthread_mutex_unlock(&count_lock);
}

/* 线程2 */
increment_count()
{
    pthread_mutex_lock(&count_lock);
    count = 2;
    // pthread_mutex_unlock(&count_lock);
    pthread_cond_signal(&count_nonzero);
    pthread_mutex_unlock(&count_lock);
}

/ 线程1 执行decrement_count()
[1] 对互斥量count_lock加锁
[2] 如果count为0,则执行pthread_cond_wait(),
    pthread_cond_wait会自动把调用线程放到等待条件的线程列表上,对互斥量count_lock解锁,此时该线程挂起。
[3] 如果count不为0,则执行count减1,然后解锁count_lock

// 线程2 执行increment_count()
[1] 对互斥量count_lock加锁
[2] count赋值为2
[3] 如果count不为0,则执行pthread_cond_signal(),给线程1发送信号,唤醒正在等待的线程1
[4] 解锁count_lock
然后线程1重新执行函数decrement_count()

Q:为什么decrement_count()函数中使用while循环来判断条件?
A:pthread_cond_signal()至少能唤醒一个等待该条件的线程,如果有多个线程正在阻塞等待该条件变量,则调度策略确定线程解除阻塞的顺序。
pthread_cond_signal()在多处理器上可能同时唤醒多个线程,当只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续等待。
对于线程池,pthread_cond_broadcast()会唤醒等待该条件的所有线程,但通常我们只需要一部分线程去执行任务,所以其它的线程需要继续等待。
The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).If more than one thread is blocked on a condition variable, the scheduling policy shall determine the order in which threads are unblocked.

Q:pthread_mutex_unlock放在pthread_cond_signal前还是后?
A:互斥量mutex的目的是为了对某个资源进行互斥性的存取,确保同一时间只有一个线程访问数据。
1、pthread_mutex_unlock放在pthread_cond_signal后
如果线程2执行pthread_cond_signal后,由于系统调度的原因线程1获取CPU,那么线程1开始执行decrement_count,需要加锁count_lock,
但此时count_lock被线程2使用(加锁),所以线程1被迫再次进入休眠。线程2执行pthread_mutex_unlock,线程1再次被唤醒。
在多线程环境中,这种情况频繁发生的话会影响性能。
LinuxThreads或NPTL(Native POSIX Thread Library)中,就不会出现这个问题。因为在Linux线程中有两个队列cond_wait队列和mutex_lock队列,
pthread_cond_signal只是让线程从cond_wait队列移到mutex_lock队列,而不用返回到用户空间,不会有性能耗损。
因此Linux中推荐使用这种方式
2、pthread_mutex_unlock放在pthread_cond_signal前
缺点:在执行pthread_mutex_unlock后,执行pthread_cond_signal前,可能会出现低级别的线程(正在等待mutex锁)抢占高级别的线程(cond_wait的线程)。

注意:pthread_cond_wait必须放在pthread_mutex_lock和pthread_mutex_unlock直接

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值