linnux同步方法多种锁介绍

本文介绍了一种基于互斥锁和条件变量实现的循环缓冲区同步机制。通过使用互斥锁来保护缓冲区的访问,并利用条件变量进行生产者与消费者的同步通知,实现了循环缓冲区的高效读写操作。

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

https://blog.youkuaiyun.com/zsf8701/article/details/7844316

1.互斥锁

2.自旋锁

3.读写锁

4.文件锁

5.条件变量

6.信号量

 

https://blog.youkuaiyun.com/I_am_JoJo/article/details/7592298

 

 

linux下多种锁的比较

https://blog.youkuaiyun.com/kowzb/article/details/77160249

 

 

https://www.cnblogs.com/cchust/p/4252500.html

 

递归与不可递归锁

http://blog.chinaunix.net/uid-26983585-id-3316794.html

 

生产者消费者

https://blog.youkuaiyun.com/yusiguyuan/article/details/48265205

 

1.生产者消费者两种实现方式(信号量,信号量与互斥锁,互斥锁与条件变量)
2.信号量实现读写锁

https://www.cnblogs.com/xybaby/p/6559212.html

 

缓冲区使用

/*
已知循环缓冲区是一个可以无限循环读写的缓冲区,当缓冲区满了还继续写的话就会覆盖我们还没读取到的数据。下面定义了一个循环缓冲区并初始化,请编写它的write函数,确保不会破坏将要读取的数据,编写read函数确保读取的buf是已经写入的数据,请处理好读写的rd_pos与wr_pos的值。
*/

#include <stdio.h>
#include <pthread.h>
#include <string.h>


#define	BUF_SIZE  64

#define	WRITE_SIZE 4

#define	READ_SIZE	  64



typedef struct _ring_buf {
	char *buf;
	unsigned int buf_size;
	unsigned int rd_pos;
	unsigned int wr_pos;
	unsigned int diff_pos;
	pthread_mutex_t mutex;
	pthread_cond_t cond;
}ring_buf;
 
 
 
 
ring_buf  ring_head; 
 
 
 
void Init(ring_buf *p_ring, char *buf, unsigned int size) {
	memset(p_ring, 0, sizeof(ring_buf));
	p_ring->buf = buf;
	p_ring->buf_size = size;
	p_ring->rd_pos = 0;
	p_ring->wr_pos = 0;
	p_ring->diff_pos = p_ring->wr_pos - p_ring->rd_pos;
	pthread_mutex_init(&p_ring->mutex, NULL);
	pthread_cond_init(&p_ring->cond, NULL);
}






int deal_read_pos(int read_size) {
	int wr_pos,rd_pos,diff_pos,remain_size;
	
	if(read_size > ring_head.buf_size) {
		printf("read size errro,bigger than max size\n");	
		return -1;
	}
	wr_pos = ring_head.wr_pos;
	rd_pos = ring_head.rd_pos;
	diff_pos = ring_head.diff_pos;
	
	if(wr_pos == rd_pos) {
		if(diff_pos == ring_head.buf_size) {
			return ring_head.buf_size;
		} else {//diff_pos = 0
			printf("no read space here %s %d\n", __FUNCTION__, __LINE__);
			return 0;
		}
	} else if(wr_pos > rd_pos) {
		ring_head.diff_pos = wr_pos - rd_pos;	
		remain_size = ring_head.diff_pos;
		if(read_size > remain_size) {
			printf("no read space here %s %d\n", __FUNCTION__, __LINE__);
			return 0;			
		} else {  //read_size <= remain_size
			return remain_size;
		}
	} else if(wr_pos < rd_pos) {
		ring_head.diff_pos = ring_head.buf_size - rd_pos + wr_pos;	
		remain_size = ring_head.diff_pos;
		if(read_size > remain_size) {
			printf("no read space here %s %d\n", __FUNCTION__, __LINE__);
			return 0;			
		} else {  //write_size <= remain_size
			return remain_size;
		}
	}


}



void *read_fun(void *arg) {
	
	printf("%s start here~%d~~\n", __FUNCTION__, __LINE__);
	while(1) {
		
		pthread_mutex_lock(&ring_head.mutex);	
		if(deal_read_pos(READ_SIZE) > 0) {
			ring_head.rd_pos  = (ring_head.rd_pos + READ_SIZE)%ring_head.buf_size;
			ring_head.diff_pos = ring_head.diff_pos - READ_SIZE;
			printf("read---->write_pos:%d read_pos:%d diff_pos:%d\n", ring_head.wr_pos, ring_head.rd_pos, ring_head.diff_pos);
			pthread_cond_signal(&ring_head.cond);
		} else {
			printf("~~~~~wait write~~~~~write_pos:%d read_pos:%d diff_pos:%d\n", ring_head.wr_pos, ring_head.rd_pos, ring_head.diff_pos);
			pthread_cond_wait(&ring_head.cond, &ring_head.mutex);	
		}
		
		pthread_mutex_unlock(&ring_head.mutex);	
		usleep(1000*1000);
	}
	return;
}



/*
fun:judge we can write write_size or not
write_size:need to allocate size to write
return:return remain space to write,or return 0 cannot get remain size
*/

int deal_write_pos(int write_size) {
	int wr_pos,rd_pos,diff_pos,remain_size;
	
	
	if(write_size > ring_head.buf_size) {
		printf("write size errro,bigger than max size\n");	
		return -1;
	}
	wr_pos = ring_head.wr_pos;
	rd_pos = ring_head.rd_pos;
	diff_pos = ring_head.diff_pos;
	
	if(wr_pos == rd_pos) {
		if(diff_pos == ring_head.buf_size) {
			printf("no write space here %s %d\n", __FUNCTION__, __LINE__);	
			return 0;
		} else {//diff_pos = 0
			return ring_head.buf_size;//remain size to write	
		}
	} else if(wr_pos > rd_pos) {
		ring_head.diff_pos = wr_pos - rd_pos;	
		remain_size = ring_head.buf_size - ring_head.diff_pos;
		if(write_size > remain_size) {
			printf("no write space here %s %d\n", __FUNCTION__, __LINE__);	
			return 0;			
		} else {  //write_size <= remain_size
			return remain_size;
		}
	} else if(wr_pos < rd_pos) {
		ring_head.diff_pos = ring_head.buf_size - rd_pos + wr_pos;	
		remain_size = ring_head.buf_size - ring_head.diff_pos;
		if(write_size > remain_size) {
			printf("no write space here %s %d\n", __FUNCTION__, __LINE__);	
			return 0;			
		} else {  //write_size <= remain_size
			return remain_size;
		}
	}
}

void *write_fun(void *arg) {
	
	printf("%s start here~%d~~\n", __FUNCTION__, __LINE__);
	while(1) {
		
		pthread_mutex_lock(&ring_head.mutex);	
		
		
		if(deal_write_pos(WRITE_SIZE) > 0) {
			ring_head.wr_pos  = (ring_head.wr_pos + WRITE_SIZE)%ring_head.buf_size;
			ring_head.diff_pos = ring_head.diff_pos + WRITE_SIZE;
			printf("write---->write_pos:%d read_pos:%d diff_pos:%d\n", ring_head.wr_pos, ring_head.rd_pos, ring_head.diff_pos);
			
			pthread_cond_signal(&ring_head.cond);
		} else {
			printf("~~~~~wait read~~~~~write_pos:%d read_pos:%d diff_pos:%d\n", ring_head.wr_pos, ring_head.rd_pos, ring_head.diff_pos);
			pthread_cond_wait(&ring_head.cond, &ring_head.mutex);	
		}
		pthread_mutex_unlock(&ring_head.mutex);	
		usleep(1000*1000);
		
	}
	return;
}

int main(void) {
	char buf[BUF_SIZE] = {0};
	
	pthread_t read_t;
	pthread_t write_t;
	int ret = -1;
	
	Init(&ring_head, buf, BUF_SIZE);
	
	ret = pthread_create(&read_t, NULL, read_fun, NULL);
	if(ret != 0) {
		printf("pthread create fail here %s  %d\n", __FUNCTION__, __LINE__);
		return -1;
	}
	
	ret = pthread_create(&write_t, NULL, write_fun, NULL);
	if(ret != 0) {
		printf("pthread create fail here %s  %d\n", __FUNCTION__, __LINE__);
		return -1;
	}	
	
	printf("start here~~~\n");
	
	
	pthread_join(read_t, NULL);
	pthread_join(write_t, NULL);
	printf("end here~~\n");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值