深入理解 pthread_cond_wait()

在多线程同步互斥的应用场景下,通常会用到pthread_cond_wait()和pthread_cond_signal()函数。那么这两个函数到底是如何保证互斥同步的呢?

为了对上面的问题有个直观的了解,可以从下面的问题着手。下面两段这些程序有什么bug么?

a. 等待条件的线程执行的代码:

Thread
1:

{

……………………..

pthread_cond_wait(cv,
mutex);

do_worker_task();

……………………..

}

b.唤醒等待线程的代码:

{

pthread_mutex_lock(mutx);

pthread_cond_signal(cv)

pthread_mutex_unlock(mutex);

}

要知道上面代码问题在哪,关键是必须对pthread_cond_wait()有深入的了解。为了对这个函数又直观的了解,下面给出了pthread_cond_wait(cv,
mutex)正常执行过程中的几个重要子步骤伪码:

pthread_cond_wait(cv,
mutex) 实际做的事情:

a.
pthread_mutex_unlock(mutex);

b.
do_real_cond_wait(cv); // 可能在这阻塞直到其他线程调用pthread_cond_signal(cv)或者  pthread_cond_broadcast(cv),才会往下执行

c.
pthread_mutex_lock(mutex);

结合在多处理器、多线程、高并发的环境下,上面三个步骤就显得缺一不可,才能保证尽可能地互斥:

步骤a:保证其他线程此后也有等待、申请条件变量的同等机会

步骤b:在条件变量还没就绪的情况下,执行真正的阻塞

步骤c:当前线程得到条件变量之后,阻止其他等待条件变量的线程继续往下执行,而自己可以往下执行。

那么问题来了,考虑步骤c,如果单独一句pthread_cond_wait(cv,
mutex)是无法确保线程尽可能互斥的,这就是为何在执行pthread_cond_wait()之前要求有pthread_mutex_lock(mutx)的原因了,因此正常申请条件变量的线程的流程应该如下:

Thread
1:

{

pthread_mutex_lock(mutx);

pthread_cond_wait(cv,
mutex);

do_worker_task();

pthread_mutex_unlock(mutex);

}

至于释放条件变量,理解了上边的内部机制之后,其实在释放条件变量之前就不需要申请锁再释放锁了。

这里要特别提到的一点是,按照上面正确申请条件变量的的流程,仍然存在多个等待条件变量的线程同时执行步骤b出等待,此时如果有信号释放,就会唤醒多个线程。这也就是为什么手册上说pthread_cond_signal(cv)至少唤醒一个在等待cv的线程(可以计数资源为1)的原因了。

参考文档和手册:

man
pthread_cond_signal

时间: 2024-10-05 19:50:42

深入理解 pthread_cond_wait()的相关文章

深入理解pthread_cond_wait、pthread_cond_signal

===============================man pthread_cond_wait的解释========================== LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数.但这个函数的执行过程比较难于理解. pthread_cond_wait()的工作流程如下(以MAN中的EXAMPLE为例): Consider two shared variables x and y, protected

主线程和子线程的同步控制

一个线程的结束有两种途径,一种是象我们以下的样例一样.函数结束了.调用它的线程也就结束了.还有一种方式是通过函数pthread_exit来实现.另外须要说明的是,一个线程不能被多个线程等待,也就是说对一个线程仅仅能调用一次pthread_join.否则仅仅有一个能正确返回.其它的将返回ESRCH 错误. 在Linux中,默认情况下是在一个线程被创建后.必须使用此函数对创建的线程进行资源回收,可是能够设置Threads attributes来设置当一个线程结束时.直接回收此线程所占用的系统资源.具

NPTL 线程同步方式

NPTL提供了互斥体 pthread_mutex_t 类型进行线程同步,防止由于多线程并发对全局变量造成的不正确操作.使用 pthread_mutext_t 对数据进行保护已经可以实现基本的数据同步,NPTL又提供了pthread_cond_t 条件变量与pthread_mutext_t一起使用实现高效的线程同步保护数据.有了互斥变量pthread_mutext_t为什么还要引入条件变量pthread_cond_t呢? 原因就是防止CPU空转,一个线程获得互斥量之后,另外一个线程如果想获取该互斥

linuxc线程信号-pthread_cond_wait理解

pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t*mutex)函数 传入的参数mutex用于保护条件,因为我们在调用pthread_cond_wait时,如果条件不成立我们就进入阻塞,但是进入阻塞这个期间,如果条件变量改变了的话,那我们就漏掉了这个条件.因为这个线程还没有放到等待队列上,所以调用pthread_cond_wait前要先锁互斥量, 即调用pthread_mutex_lock(),pthread_cond_wait在把线程

pthread_cond_wait()函数的理解(摘录)

/************pthread_cond_wait()的使用方法**********/pthread_mutex_lock(&qlock);    /*lock*/pthread_cond_wait(&qready, &qlock); /*block-->unlock-->wait() return-->lock*/pthread_mutex_unlock(&qlock); /*unlock*/ /************************

pthread_cond_wait() 前使用 while 讲解

pthread_cond_wait() 前使用 while 讲解 2009-10-27 9:33 LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数.但这个函数的执行过程比较难于理解. pthread_cond_wait()的工作流程如下(以MAN中的EXAMPLE为例): Consider two shared variables x and y, protected by the mutex mut, and a conditio

pthread_cond_wait() 详解

了解 pthread_cond_wait() 的作用非常重要 -- 它是 POSIX 线程信号发送系统的核心,也是最难以理解的部分. 首先,让我们考虑以下情况:线程为查看已链接列表而锁定了互斥对象,然而该列表恰巧是空的.这一特定线程什么也干不了 -- 其设计意图是从列表中除去节点,但是现在却没有节点.因此,它只能: 锁定互斥对象时,线程将调用 pthread_cond_wait(&mycond,&mymutex).pthread_cond_wait() 调用相当复杂,因此我们每次只执行它的

pthread_cond_wait、pthread_cond_signal 不深入的思考

编程中,当涉及到多个线程需要访问同一个全局对象时,往往需要进行线程同步,而线程同步,往往是一个约定俗成的东西.比如说: 1 //*.cpp 2 int g_var ; pthread_mutex_t g_mtx ; 3 static void * threadFunc(void * Par) { 4 pthread_mutex_lock(&g_mtx) ; 5 6 g_var = //some value ; 7 8 return NULL ; 9 } 为了保持g_var的一致性,理应在所有线程

深入理解 iOS 开发中的锁

来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大量的实战经验,另一方面这样的文章相当多,比如 iOS中保证线程安全的几种方式与性能对比.iOS 常见知识点(三):Lock.本文也不会详细介绍锁的具体实现原理,这会涉及到太多相关知识,笔者不敢误人子弟. 本文要做的就是简单的分析 iOS 开发中常见的几种锁如何实现,以及优缺点是什么,为什么会有性能上