1、这个是针对线程来说的,都以线程作为例子。
2、互斥锁(mutual exclusion) 用于保护临界区(critical region),posix互斥锁用变量pthread_mutex_t声明。
如果互斥锁变量是静态分配的,用PTHREAD_MUTEX_INITIALIZER 初始化,如果是动态分配(比如:malloc)通过运行pthread_mutex_init初始化。
如:
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t *mutex2 = malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(mutex2, NULL);
3、互斥锁上锁解锁函数:
int pthread_mutex_lock(pthread_mutex_t *mptr); 阻塞
int pthread_mutex_trylock(pthread_mutex_t *mptr); 马上返回,如果有其他线程用mptr则返回EBUSY错误。
int pthread_mutex_unlock(pthread_mutex_t *mptr);
技巧:将要共享的条件变量和用到的互斥锁放在一个结构体中,便于访问。
4、条件变量:用于等待某事件发生。
类型:pthread_cond_t ; 静态初始化用PTHREAD_COND_INITIALIZER
函数:
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr):唤醒等待在相应条件变量上的一个线程。
int pthread_cond_broadcast(pthread_cond_t *cptr):唤醒等待在相应条件变量上的所有线程。
int pthread_cond_timedwait(pthread_cond_t *cptr, pthread_t *mptr, const struct timespec *abstime);
struct timespec
{
time_t tv_sec;
long tv_nsec; /* 纳秒 */
};
超时情况返回错误:ETIMEDOUT, 另外 abstime 是绝对时间,绝对时间是utc时间1970年1月1号以来的描述和纳秒数。
5、一般化代码:
给条件变量发送信号的代码一般如下:
struct
{
Pthread_mutex_t mutex;
Pthread_cond_t cond;
/* cond需要同步的变量 */
}var = {PTHREAD_MUTEx_INITIALIZER, PTHREAD_COND_INITIALIZER, …};
Pthread_mutex_lock(& var.mutex);
/* 设置条件为真 */
Pthread_cond_signal(&var.cond);
Pthread_mutex_unlock(&var.mutex);
测试条件并进入睡眠以等待该条件为真的代码大体如下:
pthread_mutex_lock(& var.mutex );
while( 条件为假 )
pthread_cond_wait(&var.cond, &var.mutex);
/* 修改条件 */
pthread_mutex_unlock(& var.mutex );
说明:
(1)、pthread_cond_wait以原子性的做以下步骤:给互斥锁var.mutex解锁,然后把调度线程投入睡眠到另外某个线程就本条件变量调用pthread_cond_signal或者pthread_cond_broadcast,在返回前在给var.mutex上锁。
(2)、测试条件中用while的原因是再次测试条件是否成立,以避免可能发生虚假唤醒。
(3)、为了避免所谓的上锁冲突,即为:在一个线程调用pthread_cond_signal后,还没有释放互斥说var.mutex就转到了检测条件的线程,该线程马上挂起,为了比避免这种情况,将发送条件变量部分代码改为:
int dosignal = 0;
pthread_mutex_lock(&var.mutex);
dosignal = (var.条件为真);
/* 修改条件 */
pthread_mutex_unlock(&var.mutex);
if( dosignal )
pthread_cond_signal(&var.cond);
6、互斥锁和条件变量的属性。(条件变量的函数在下面函数中将mutex换成cond即可)
静态分配的不用destroy。
int pthread_mutex_init(pthread_mutex_t *mptr, const pthread_mutexattr *attr);
int pthread_mutex_destroy(pthread_mutex_t *mptr);
int pthread_mutexattr_init(pthread_mutexattr_t *mptr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *mptr);
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *valptr);
int pthread_mutexattr_setpshared(const pthread_mutexattr_t *attr, int value);
value的值可以为:PTHREAD_PROCESS_SHARED称为进程间共享属性。