线程同步
线程同步概念
互斥锁
读写锁
死锁
条件变量
本身不是锁,但通常结合锁来使用
生产者消费者模型
/*************************************************************************
> File Name: producer_consumer_test.c
> Author: shaozheming
> Mail: 957510530@qq.com
> Created Time: 2022年03月03日 星期四 10时43分40秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
/* 链表作为共享数据,需被互斥量保护 */
struct msg {
struct msg *next;
int num;
};
struct msg *head;
/* 静态初始化一个条件变量和一个互斥量 */
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *consumer(void *p)
{
struct msg *mp;
for(;;) {
pthread_mutex_lock(&lock);
while(head == NULL){
pthread_cond_wait(&has_product, &lock);
}
mp = head;
head = mp->next; //模拟消费掉一个产品
pthread_mutex_unlock(&lock);
printf("--Consume %lu---%d\n", pthread_self(), mp->num);
free(mp);
sleep(rand() % 5);
}
}
void *producer(void *p)
{
struct msg *mp;
for(;;){
mp = malloc(sizeof(struct msg));
mp->num = rand() % 1000 + 1;//模拟生产一个产品
printf("-Produce--------------%d\n", mp->num);
pthread_mutex_lock(&lock);
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&has_product); //将等待在该条件变量上的一个线程唤醒
sleep(rand() % 5);
}
}
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char* argv[])
{
pthread_t pid, cid;
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
信号量
相当于初始化为N的互斥量,N值表示同时访问共享区的线程数。
相对时间:是自己当前时间为基准
绝对时间:Linux操作系统开始算
生产者消费者模型
/*************************************************************************
> File Name: producer_consumer_test.c
> Author: shaozheming
> Mail: 957510530@qq.com
> Created Time: 2022年03月03日 星期四 10时43分40秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM 5
int queue[NUM]; //全局数组实现环形队列
sem_t blank_number, product_number; //空格子信号量,产品信号量
void *consumer(void *arg)
{
int i = 0;
while(1) {
sem_wait(&product_number); //消费者产品数--,为0等待
printf("----Consume----%d\n", queue[i]);
queue[i] = 0; //消费一个产品
sem_post(&blank_number); //消费掉之后,将空格子数++
i = (i+1) % NUM;
sleep(rand() % 3);
}
}
void *producer(void *arg)
{
int i = 0;
while(1) {
sem_wait(&blank_number); //生产者空格子数--,为0等待
queue[i] = rand() % 1000 + 1; //生产一个产品
printf("----Produce----%d\n", queue[i]);
sem_post(&product_number); //将产品数++
i = (i+1) % NUM;
sleep(rand()%1); //借助下标实现环形
}
}
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char* argv[])
{
pthread_t pid, cid;
sem_init(&blank_number, 0, NUM);
sem_init(&product_number, 0, 0);
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
sem_destroy(&blank_number);
sem_destroy(&product_number);
return 0;
}
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈