Linux 之多线程编程-条件变量与互斥锁

博客介绍了同步机制中的互斥锁、条件变量和读写锁。互斥锁以排他方式防止数据并发访问,介绍了其初始化、申请、释放和销毁操作;条件变量的操作涉及初始化、通知和等待;读写锁操作与互斥锁类似,但占用资源少。还给出了互斥锁和条件变量结合的生产者消费者例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

一、互斥锁
互斥锁是一个二元变量,主要以排他的方式防止数据被并发访问。
1、初始化互斥锁

#include <pthread.h>
/*动态初始化互斥锁*/
int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr);

/*静态态初始化互斥锁*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALZER;

函数第一个参数指向要初始化的互斥锁,第二个参数为互斥锁的属性,为NULL,则表示使用默认属性。

2、申请使用互斥锁

#include <pthread.h>
/*以阻塞方式上锁*/
int pthread_mutex_lock(pthread_mutex_t* mutex);

/*以非阻塞方式上锁*/
int pthread_mutex_trylock(pthread_mutex_t* mutex);

3、释放互斥锁

#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t* mutex);

释放操作只能由占用该互斥锁的线程完成。

4、销毁互斥锁

#include <pthread.h>
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  <stdio.h>
#include <stdlib.h>
#include <pthread.h>

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()后进入等待状态时,会把互斥锁解锁,并阻塞等待加锁后,才会继续消费。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值