关于条件变量这一节的知识几乎惹怒了我,不知道是原书就不好,还是翻译的不好,还是我笨的原因,总而言之就是看不懂。
现在说一下我的理解:
条件变量虽说是和某个谓词绑定,但是其实只是程序员的工作,并没有真正的绑定。
使用条件变量的场景是,一个队列空了,我们要等待它不为空,虽然也不知道谁规定的,大家都用while,而不用if
while(QUEUE_IS_EMPTY())
{
pthread_cond_wait(&cond,&mutex);
}
/************************************************************************* > File Name: lifecycle.c > Author: likeyi > Mail: likeyiyy@sina.com > Created Time: Thu 17 Apr 2014 11:00:08 AM CST ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int a,b; void * delay_print(void * arg) { pthread_detach(pthread_self()); sleep(1); printf("Hello world\n"); a = 7; b = 8; pthread_cond_signal(&cond); } int main(int argc,char * argv[]) { pthread_t tid; int result = pthread_create(&tid,NULL,delay_print,NULL); if(result != 0) { printf("create thread error\n"); exit(0); } printf("printf form main\n"); a = 6; b = 5; if(a != b) { pthread_cond_wait(&cond,&mutex); } printf("a= %d b = %d\n",a,b); pthread_exit(&result); }
如上面的代码所示,当a不等于b时我们就等待,从这个逻辑上来说我们是期望当a等于b的时候把我们唤醒。
然而事实上,这个绑定只是程序员的主观愿望,上面的代码,在子线程中我们让a=8,b=9,然后调用了pthread_cond_signal,仍然唤醒了主线程。
这是多么不好的语义啊,完全靠程序员自己来进行绑定啊。
有没有一种操作是原子的等待wait bool is 1
比如说atomic_wait(a==b),我希望有这样的函数。
/***********************************************************************************************************/
从上面的代码我们也能看出,之所以要用while而不用if的原因,书上讲了三个原因:
被拦截的唤醒,松散的唤醒,假唤醒。不知道假唤醒是不是我这样的假的唤醒。
总而言之:总是在while循环中测试谓词来等待条件变量。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int a,b; void * delay_print(void * arg) { pthread_detach(pthread_self()); sleep(1); printf("Hello world\n"); a = 8; b = 8; pthread_cond_signal(&cond); } int main(int argc,char * argv[]) { pthread_t tid; int result = pthread_create(&tid,NULL,delay_print,NULL); if(result != 0) { printf("create thread error\n"); exit(0); } printf("printf form main\n"); a = 6; b = 5; while(a != b) { pthread_cond_wait(&cond,&mutex); } printf("a= %d b = %d\n",a,b); pthread_exit(&result); }
一个条件变量只能对应一个互斥量。
一个互斥量可以对应多个条件变量。
mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),
且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),
而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。
在条件满足从而离开pthread_cond_wait()之前,
mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。