IPC同步 笔记之 互斥锁与条件变量

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称为进程间共享属性。



你可能感兴趣的:(struct,测试,null,Signal)