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;
}