线程同步

线程同步概念

image
image

互斥锁

image
image
image
image

读写锁

image
image
image
image
image

死锁

image

条件变量

本身不是锁,但通常结合锁来使用
image
image
image

生产者消费者模型

image

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

image

信号量

相当于初始化为N的互斥量,N值表示同时访问共享区的线程数。
image
image
image
image
相对时间:是自己当前时间为基准
绝对时间:Linux操作系统开始算
生产者消费者模型
image

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

posted @ 2022-03-02 19:58  蘑菇王国大聪明  阅读(18)  评论(0编辑  收藏  举报