怎样同步多个线程或多个进程的活动?为允许在线程或进程间共享数据,同步通常是必须的。互斥锁和条件变量是同步的基本组成部分。
互斥锁
互斥锁指代相互排斥,它是最基本的同步形式。互斥锁用于保护临界区,以保证任何时刻只有一个线程在执行其中的代码。
下面函数给一个互斥锁上锁和解锁:
#include<pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mptr);
int pthread_mutex_unlock(pthread_mutex_t *mptr);
条件变量
互斥锁用于上锁,条件变量则用于等待。条件变量总是有一个互斥锁与之关联。
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr,pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cont_t *cptr);
测试条件并进入睡眠以等待该条件变为真的代码大体如下:
pthread_mutex_lock(&mutex);
while(条件为假)
pthread_cond_wait(&cond,&mutex);
修改条件
pthread_mutex_unlock(&mutex);
信号量
信号量(semaphore)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语。
二值信号量可用于互斥目的,就像互斥锁一样。
初始化信号量为1;
sem_wait(&sem);
临界区
sem_post(&sem);
信号量、互斥锁和条件变量之间的差异
(1)互斥锁必须总是由给它上锁的线程解锁,信号量的挂出却不必由执行过它的等待操作的同一线程执行。
(2)互斥锁要么被锁住,要么被解开(二值状态,类似于二值信号量)。
(3)既然信号量有一个与之关联的状态(它的计数值),那么信号量挂出操作总是被记住。然而当向一个条件变量发送信号时,如果没有线程等待在该条件变量上,那么该信号将丢失。