进程间同步(1)——条件变量和互斥量
1. 概述
条件变量和互斥量是最基本的同步形式,总是用于同步同一个进程的各个线程间同步。
当把条件变量或互斥量放在共享内存区时,可用于进程间同步。
同样的情况还有读写锁,它们都是随进程的持续性。
2.互斥锁
互斥锁指代相互排斥,用于保护临界区。多个线程和多个进程分享的共享数据。
静态初始化:static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
动态初始化:互斥锁是动态分配的,pthread_mutex_init(&mutex);初始化
上锁和解锁
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mptr);
int pthread_mutex_trylock(pthread_mutex_t *nptr); //非阻塞上锁,出错EBUSY
int pthread_mutex_unlock(pthread_mutex_t *mptr);
成功:0; 出错:EXXX
管道,消息队列的同步是隐式的,内核会处理同步。
共享缓冲区,线程间的必须是显示同步。
加锁和解锁必须是同一个线程,信号量没有这个限制。
3.等待与信号发送
互斥锁用于上锁,不能用于等待。信号量两者都可以。
条件变量pthread_cond_t用于等待。
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);//等待某一条件变量被发送,此时会解锁互斥量。唤醒后会重新加锁
int pthread_cond_singal(pthread_cond_t *cptr);//信号发送
成功: 0; 出错:正的EXXX
每个条件变量都有一个信号量与之相关联,wait等待某个条件为真时,会指定其条件变量的地址和所关联的互斥锁的地址,目的是用互斥锁给条件变量加锁。
注意:在等待条件变量时要检测条件
while(条件为假){//可能有虚假的唤醒
pthread_cond_wait(…);
}
4.属性
对于条件变量我们可以pthread_cond_broadcast广播,和pthread_cond_timewait定时等待。
条件变量和互斥锁默认具有单个进程的线程间共享属性PTHREAD_PROCESS_PRIVATE, 可以改变为进程间共享属性PTHREAD_PROCESS_SHARED。
//先初始化属性,再设置共享,最后初始化互斥锁
pthread_mutexattr_t mattr;
pthread_mutexattr_init(&mattr);
pthread_mutexattr_setshared(&mattr, PTHREAD_PROCESS_SHARED);//在进程间共享互斥锁,锁要放在共享内存区
//使用属性初始化锁
pthread_mutex_t *mptr;
pthread_mutex_init(mptr, &mattr);
可以利用同样的方法初始化pthread_cond_t