这次的博文主要解释互斥锁和条件变量:
首先介绍相关的函数:
互斥量:
int pthread_mutex_init(pthread_mutex_t mutex, pthread_mutexattr_t attr) 这是动态初始化互斥锁,还可以静态初始化,pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER 互斥锁刚刚初始化后处于无锁状态。
int pthread_mutex_lock(pthread_mutex_t *mutex) 阻塞式函数,当互斥量已上锁,就阻塞等待。
int pthread_mutex_lock(pthread_mutex_t *mutex) 非阻塞,如果互斥量已上锁就返回EBUSY的错误
int pthread_mutex_unlock(pthread_mutex_t *mutex) 解锁
说明:互斥量的作用:在多线程共享数据区的时候,保护在临界区的被操作的数据
对应的,条件变量:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);和互斥量类似,这是条件变量的动态初始化函数,也可以静态初始化,pthread_cond_t cond = PTHREAD_COND_INITIALIZER
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) 这个函数执行后会释放互斥锁,阻塞等待信号量为真和互斥锁解锁,然后才再次唤醒。
int pthread_cond_signal(pthread_cond_t * cond) 改变条件变量为真,也就是为上面的函数,提供满足条件。
int pthread_cond_broadcast(pthread_cond_t *cond) 唤醒所有因此条件变量阻塞的线程,这是所有线程会竞相争取各自资源。关于其与pthread_cond_signal的区别,就是pthread_cond_signal至少唤醒一个线程,而pthread_cond_broadcast是要唤醒全部线程(谨慎使用)。
线程相关的函数:
void pthread_exit(void *retval);
这个函数是线程主动要求退出,因为多线程有可能共享资源,所以线程退出后不会释放资源,如果需要同步释放资源可使用pthread_jion同步释放。
int pthread_join(pthread_t thread_id, void ** retval) 阻塞等待线程退出,同步释放资源,如果线程已经退出,函数会立即返回。
下面是代码及运行结果:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t count_lock;
pthread_cond_t count_nonzero;
unsigned count = 0;
void * decrement_count(void *arg)
{
pthread_mutex_lock (&count_lock);
printf("decrement_count get count_lock\n");
while(count==0)
{
printf("decrement_count count == 0 \n");
printf("decrement_count before cond_wait \n");
pthread_cond_wait( &count_nonzero, &count_lock);
printf("decrement_count after cond_wait \n");
}
count = count -1;
printf("decrement_count before count_unlock\n");
pthread_mutex_unlock (&count_lock);
}
void * increment_count(void *arg)
{
pthread_mutex_lock(&count_lock);
printf("increment_count get count_lock\n");
if(count==0)
{
printf("increment_count before cond_signal\n");
pthread_cond_signal(&count_nonzero);
printf("increment_count after cond_signal\n");
}
count=count+1;
printf("increment_count before count_unlock\n");
pthread_mutex_unlock(&count_lock);
}
int main(void)
{
pthread_t tid1,tid2;
pthread_mutex_init(&count_lock,NULL);
pthread_cond_init(&count_nonzero,NULL);
pthread_create(&tid1,NULL,decrement_count,NULL);
sleep(2);
pthread_create(&tid2,NULL,increment_count,NULL);
sleep(10);
pthread_exit(0);
}
运行结果:
decrement_count get count_lock
decrement_count count == 0
decrement_count before cond_wait
increment_count get count_lock
increment_count before cond_signal
increment_count after cond_signal
increment_count before count_unlock
decrement_count after cond_wait
decrement_count before count_unlock