一、互斥锁
互斥锁是一个二元变量,主要以排他的方式防止数据被并发访问。
1、初始化互斥锁
#include
/*动态初始化互斥锁*/
int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr);
/*静态态初始化互斥锁*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALZER;
函数第一个参数指向要初始化的互斥锁,第二个参数为互斥锁的属性,为NULL,则表示使用默认属性。
2、申请使用互斥锁
#include
/*以阻塞方式上锁*/
int pthread_mutex_lock(pthread_mutex_t* mutex);
/*以非阻塞方式上锁*/
int pthread_mutex_trylock(pthread_mutex_t* mutex);
3、释放互斥锁
#include
int pthread_mutex_unlock(pthread_mutex_t* mutex);
释放操作只能由占用该互斥锁的线程完成。
4、销毁互斥锁
#include
int pthread_mutex_destroy(pthread_mutex_t* mutex);
以上所有函数执行成功都是返回0。
二、条件变量
1、初始化条件变量
int pthread_cond_init(pthread_cond_t* cond,pthread_condattr_t* attr);
函数第一个参数指向要初始化的条件变量,第二个参数为条件变量的属性,为NULL,则表示使用默认属性。
2、通知等待条件变量的线程
/*通知等待的第一个线程*/
int pthread_cond_signal(pthread_cond_t* cond);
/*通知等待的所有线程*/
int pthread_cond_broadcast(pthread_cond_t* cond);
3、等待条件变量
/*阻塞等待某个条件变量*/
int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex);
/*超时等待某个条件变量*/
int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex,struct timespec* abstime);
从函数声明可以看出,两个函数都包含了互斥锁,所以,若某个线程因等待条件变量进入等待状态,将隐含的释放申请到的互斥锁,在返回时,将隐含的申请互斥锁,函数执行成功返回0。
三、读写锁
读写锁的操作与互斥锁基本相同,但占用资源相对于互斥锁要少很多,大概逻辑就是读锁锁定时,其他线程可以读,但不可以写,写锁锁定时,其他线程的读写均不行。
下面是互斥锁和条件变量结合一起使用的生产者消费者的简单例子,但也是可以说明问题的:
#include
#include
#include
int pro = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void init()
{
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
}
void* producer(void* date)
{
while(1)
{
pthread_mutex_lock(&mutex);
pro++;
printf("生产者生产了1个,现在共%d个\n",pro);
if(pro == 3)
{
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void* contomer(void* date)
{
while(1)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pro -= 3;
printf("消费者吃了3个\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main()
{
void* ret;
pthread_t tid1,tid2;
init();
pthread_create(&tid1,NULL,producer,0);
pthread_create(&tid2,NULL,contomer,0);
pthread_join(tid1,&ret);
pthread_join(tid2,&ret);
return 0;
}
运行结果是:
从结果可以看出,当生产者生产了3个产品后,立即通知消费者来消费,紧接着,生产者继续生产,无线循环下去。里面需要注意的是消费者在调用pthread_cond_wait()后进入等待状态时,会把互斥锁解锁,并阻塞等待加锁后,才会继续消费。