条件变量 && 读写锁 介绍
条件变量提供了一种线程间的通知机制:当某个共享数据达到某个值的时候,唤醒等待这个共享数据的线程。
这个可以想象成把线程加入到一个链表中,等待被唤醒,唤醒之后执行相应的操作
主要函数:
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);//创建条件变量
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); //唤醒所有等待的线程
int pthread_cond_destroy(pthread_cond_t *cond);//销毁条件变量
读写锁简单来说就是更加细分的互斥锁,分为读锁和写锁。
加了读锁之后,可以再次添加读锁,但是不能添加写锁;添加写锁之后,不能添加读锁和写锁。
主要函数:
pthread_rwlock_rdlock(pthread_rwlock_t *lock);//加读锁
pthread_rwlock_unlock(pthread_rwlock_t *lock);//解读锁
pthread_rwlock_wrlock(pthread_rwlock_t *lock);//加写锁
pthread_rwlock_unlock(pthread_rwlock_t *lock);//解写锁
一、条件变量的使用
题目:在条件变量中加入两个线程,键盘输入数据,唤醒一个线程执行读操作,当输入“end”,唤醒所有线程,结束。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
char buff[128] = {0};
pthread_mutex_t mutex;
pthread_cond_t cond;
void* fun1(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
if(strncmp(buff,"end",3) == 0)
{
break;
}
printf("fun1 buff = %s\n",buff);
}
}
void* fun2(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
if(strncmp(buff,"end",3) == 0)
{
break;
}
printf("fun2 buff = %s\n",buff);
}
}
int main()
{
pthread_t id1,id2;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
pthread_create(&id1,NULL,fun1,NULL);
pthread_create(&id2,NULL,fun2,NULL);
while(1)
{
fgets(buff,128,stdin);
if(strncmp(buff,"end",3) == 0)
{
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
break;
}
else
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
exit(0) ;
}
运行结果:
二、读写锁的使用
题目:创建三个线程,线程一、二读,线程三写
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
pthread_rwlock_t lock;
void* fun1(void* arg)
{
while(1)
{
pthread_rwlock_rdlock(&lock);
printf("fun1 read start\n");
sleep(1);
printf("fun1 read end\n");
pthread_rwlock_unlock(&lock);
sleep(1);
}
}
void* fun2(void* arg)
{
while(1)
{
pthread_rwlock_rdlock(&lock);
printf("fun2 read start\n");
sleep(3);
printf("fun2 read end\n");
pthread_rwlock_unlock(&lock);
sleep(1);
}
}
void* fun3(void* arg)
{
while(1)
{
pthread_rwlock_wrlock(&lock);
printf("fun3 write lock\n");
sleep(4);
printf("fun3 write end\n");
pthread_rwlock_unlock(&lock);
sleep(1);
}
}
int main()
{
pthread_rwlock_init(&lock,NULL);
pthread_t id1,id2,id3;
pthread_create(&id1,NULL,fun1,NULL);
pthread_create(&id3,NULL,fun2,NULL);
pthread_create(&id3,NULL,fun3,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
}
运行结果:
这里因为写了一个简单的程序,是一个死循环,所以CTRL+C结束了进程。