在多线程编程中,线程的同步是一个宏观的概念,其实其内部的实现包含两个部分:一是互斥,二是线程之间的相互依赖关系。
就好像是一个团队开发一个软件项目,加入有两个小组,分别是:研发小组和测试小组。按照我们的经验,一个软件项目,只有当研发小组将其开发出来以后,测试小组才可以对其进行测试,这说明测试小组是依赖于研发小组的。如果我们把该软件项目看成是一个共享资源,这个情景就可以看作是一个线程的同步问题。
为了实现线程的同步,我们引入条件变量。条件变量的内部是一个等待队列,用于放置等待的线程,线程在条件变量中等待通知。
对于等待变量的操作,也是对一个共享资源的操作,所以也需要互斥锁对其进行保护。所以在线程同步的问题中,互斥锁和等待变量常常是一起使用的。
我们使用pthread_cond_wait(pthread_cond_t * cond,pthread_mutex_t * mutex)这一函数来实现等待变量的等待操作。
这里就要好好说一下pthread_cond_wait(pthread_cond_t * cond,pthread_mutex_t * mutex)这一函数的内部实现原理:
伪代码说明:
pthread_cond_wait(pthread_cond_t * cond,pthread_mutex_t * mutex)
{
1、unlock(mutex);//这里首先要将互斥锁打开,
2、lock(mutex);//然后使用互斥锁上锁
3、将线程自己插入到条件变量的等待队列当中
4、unlock(&mutex);
5、当前等待的线程阻塞<--------等待其他线程通知唤醒
6、该线程被唤醒以后,lock(&mutex);
7、将自己从等待队列中删除
}
这就能解释为什么在下图中,pthread_cond_wait(&r-> cond,&r->mutex)放在pthread_mutex_unlock(&r->mutex)之前。