进行多线程编程,因为无法知道哪个线程会在哪个时候对共享资源进行操作,因此让如何保护共享资源变得复杂,通过下面这些技术的使用,可以解决
线程之间对资源的竞争:
1 互斥量Mutex
2 信号灯Semaphore(不做介绍)
3 条件变量Conditions
互斥量:
对于这种情况,系统给我们提供了
互斥 量
.线程在取出头节点前必须要等待
互斥量
,如果此时有其他线程已经获得该
互斥量
,那么该线程将会阻塞在这里.只有等到其他线程释放掉该
互斥量
后,该线程才有可能得到该
互斥量
。互斥量从本质上说就是一把锁, 提供对共享资源的保护访问
对于互斥量的使用步骤:创建,初始化,上锁,解锁,毁锁
int
pthread_mutex_init
(pthread_mutex_t 、*mutex,const pthread_mutexattr_t *attr)
int
pthread_mutex_destroy
(pthread_mutex_t *mutex)
对共享资源的访问, 要使用互斥量进行加锁, 如果互斥量已经上了锁, 调用线程会阻塞, 直到互斥量被解锁。
int
pthread_mutex_lock
(pthread_mutex_t *mutex)
int
pthread_mutex_trylock
(pthread_mutex_t *mutex)
返回值: 成功则返回0, 出错则返回错误编号。
trylock是非阻塞调用模式, 如果互斥量没被锁住,
trylock函数将对互斥量加锁, 并获得对共享资源的访问权限; 如果互斥量被锁住了,trylock函数将不会阻塞等待而直接返回EBUSY, 表示共享资源处于忙状态
在操作完成后,必须给互斥量解锁,也就是前面所说的释放。这样其他等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。
int pthread_mutex_unlock(pthread_mutex_t *mutex)
条件变量
条件变量和互斥锁配合使用。
条件变量用来阻塞一个线程,当条件不满足时,线程解开相应的互斥锁,
并等待条件的变化。
一旦某个线程改变条件,将通知条件变量唤醒一个或多个被此条件变量阻塞的线程,这些线程将重新锁定互斥锁并检测条件是否满足。
pthread_cond_t cond;
pthread_cond_init(&cond,NULL);
条件变量
等待和激发
int pthread_cond_wait
(pthread_cond_t * cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait
(pthread_cond_t * cond,pthread_mutex_t *mutex,
const struct timespec *abstime);
typedef struct timespec
{
time_t tv_sec;
long tv_nsec;
};
激发条件:
pthread_cond_signal(pthread_cond_t *cond);
只能激活一个等待该条件的线程
pthread_cond_broadcast(pthread_cond_t *cond);
激活所有的等待进程
全过程可描述为:
线程
1
1、
pthread_mutex_lock()
上锁
2、
pthread_cond_wait()
等待
解锁
->
条件满足
->
上锁
3、
pthread_mutex_unlock
解锁
线程
2
1、
pthread_mutex_lock
2、
修改条件
3、
pthread_cond_signal()
4、
pthread_mutex_unlock