操作系统实验四——进程同步实验

实验内容:
抽烟者问题。假设⼀个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽 烟。抽烟者卷起并抽掉⼀
颗烟需要有三种材料:烟草、纸和胶⽔。⼀个抽烟者有烟草,⼀个有纸,另⼀个有胶⽔。系统中还有两
个供应者进程,它们⽆限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种
材料的抽烟者在卷起并抽掉⼀颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这⼀过程重
复进⾏。 请⽤IPC 同步机制编程,实现该问题要求的功能。

ipc.h

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <sys/sem.h> 
#include <sys/msg.h> 
#define BUFSZ 256
//建⽴或获取 ipc 的⼀组函数的原型说明
int get_ipc_id(char *proc_file,key_t key);
char *set_shm(key_t shm_key,int shm_num,int shm_flag); 
int set_msq(key_t msq_key,int msq_flag);
int set_sem(key_t sem_key,int sem_val,int sem_flag); 
int down(int sem_id);
int up(int sem_id);
/*信号灯控制⽤的共同体*/ 
typedef union semuns 
{ 
	int val;
	Sem_uns;
}
/* 消 息 结 构 体 */ 
typedef struct msgbuf 
{ 
	long mtype;
	char mtext[1];
} Msg_buf;
//⽣产消费者共享缓冲区即其有关的变量
key_t buff_key;
int buff_num; 
char *buff_ptr;
//⽣产者放产品位置的共享指针
key_t pput_key; 
int pput_num; 
int *pput_ptr;
//消费者取产品位置的共享指针
key_t cget_key;
int cget_num; 
int *cget_ptr;
//⽣产者有关的信号量
key_t prod_key; 
key_t pmtx_key;
int prod_sem; 
int pmtx_sem;
//消费者有关的信号量
key_t cons_key; 
int  cons_sem; 
key_t cmtx_key;
int cmtx_sem; 

key_t x_cons_key; 
int x_cons_sem;

key_t y_cons_key; 
int y_cons_sem;

key_t z_cons_key; 
int z_cons_sem;

int sem_val; 
int sem_flg; 
int shm_flg;

生产者代码

#include "ipc.h"
int get_ipc_id(char *proc_file, key_t key) {
 FILE *pf; int i, j;
 char line[BUFSZ], colum[BUFSZ];
 if ((pf = fopen(proc_file, "r")) == NULL) {
 perror("Proc file not open");
 exit(EXIT_FAILURE);
 }
 fgets(line, BUFSZ, pf);
 while (!feof(pf)) {
 i = j = 0;
 fgets(line, BUFSZ, pf);
 while (line[i] == ' ') i++;
 while (line[i] != ' ') colum[j++] = line[i++];
 colum[j] = '\0';
 if (atoi(colum) != key) continue;
 j = 0;
 while (line[i] == ' ') i++;
 while (line[i] != ' ') colum[j++] = line[i++];
 colum[j] = '\0';
 i = atoi(colum);
 fclose(pf);
 return i;
 }
 fclose(pf);
 return -1; }
/*
* 信号灯上的down/up 操作
* semid:信号灯数组标识符
* semnum:信号灯数组下标
* buf:操作信号灯的结构
*/
int down(int sem_id) {
 buf.sem_op = -1;
 buf.sem_num = 0;
 buf.sem_flg = SEM_UNDO;
 if ((semop(sem_id, &buf, 1)) < 0) {
 perror("down error ");
 exit(EXIT_FAILURE);
 }
 return EXIT_SUCCESS; }
int up(int sem_id) {
 struct sembuf buf;
 buf.sem_op = 1;
 buf.sem_num = 0;
 buf.sem_flg = SEM_UNDO;
 if ((semop(sem_id, &buf, 1)) < 0) {
 perror("up error ");
 exit(EXIT_FAILURE);
 }
 return EXIT_SUCCESS; }
/*
* set_sem 函数建⽴⼀个具有 n 个信号灯的信号量
* 如果建⽴成功,返回 ⼀个信号灯数组的标识符 sem_id
* 输⼊参数:
* sem_key 信号灯数组的键值
* sem_val 信号灯数组中信号灯的个数
* sem_flag 信号等数组的存取权限
*/
int set_sem(key_t sem_key, int sem_val, int sem_flg) {
 int sem_id;
 Sem_uns sem_arg;
 //测试由 sem_key 标识的信号灯数组是否已经建⽴
 if ((sem_id = get_ipc_id("/proc/sysvipc/sem", sem_key)) < 0 ) {
 //semget 新建⼀个信号灯,其标号返回到 sem_id
 if ((sem_id = semget(sem_key, 1, sem_flg)) < 0) {
 perror("semaphore create error");
 exit(EXIT_FAILURE);
 }
 //设置信号灯的初值sem_arg.val = sem_val;
 if (semctl(sem_id, 0, SETVAL, sem_arg) < 0) {
 perror("semaphore set error");
 exit(EXIT_FAILURE);
 }
 }
 return sem_id; }
/*
* set_shm 函数建⽴⼀个具有 n 个字节 的共享内存区
* 如果建⽴成功,返回 ⼀个指向该内存区⾸地址的指针 shm_buf
* 输⼊参数:
* shm_key 共享内存的键值
* shm_val 共享内存字节的⻓度
* shm_flag 共享内存的存取权限
*/
char *set_shm(key_t shm_key, int shm_num, int shm_flg) {
 int i, shm_id;
 char *shm_buf;
 //测试由 shm_key 标识的共享内存区是否已经建⽴
 if ((shm_id = get_ipc_id("/proc/sysvipc/shm", shm_key)) < 0 ) {
 //shmget 新建 ⼀个⻓度为 shm_num 字节的共享内存,其标号返回shm_id
 if ((shm_id = shmget(shm_key, shm_num, shm_flg)) < 0) {
 perror("shareMemory set error"); exit(EXIT_FAILURE);
 }
 //shmat 将由 shm_id 标识的共享内存附加给指针 shm_buf
 if ((shm_buf = (char *)shmat(shm_id, 0, 0)) < (char *)0) {
 perror("get shareMemory error"); exit(EXIT_FAILURE);
 }
 for (i = 0; i < shm_num; i++) shm_buf[i] = 0; //初始为 0
 }
 //shm_key 标识的共享内存区已经建⽴,将由 shm_id 标识的共享内存附加给指针 shm_buf
 if ((shm_buf = (char *)shmat(shm_id, 0, 0)) < (char *)0) {
 perror("get shareMemory error");
 exit(EXIT_FAILURE);
 }
 return shm_buf; }
/*
* set_msq 函数建⽴⼀个消息队列
* 如果建⽴成功,返回 ⼀个消息队列的标识符 msq_id
* 输⼊参数:
* msq_key 消息队列的键值
* msq_flag 消息队列的存取权限
*/
int set_msq(key_t msq_key, int msq_flg) 
{
	 int msq_id;
	 //测试由 msq_key 标识的消息队列是否已经建⽴
	 if ((msq_id = get_ipc_id("/proc/sysvipc/msg", msq_key)) < 0 ) {
	 //msgget 新建⼀个消息队列,其标号返回到 msq_id
	 if ((msq_id = msgget(msq_key, msq_flg)) < 0) {
	 perror("messageQueue set error"); exit(EXIT_FAILURE);
	 }
	 }
	 return msq_id; 
 }
int main(int argc,char *argv[])
{
	int rate;
	//可在在命令⾏第⼀参数指定⼀个进程睡眠秒数,以调解进程执⾏速度  
	if (argv[1] != NULL) rate = atoi(argv[1]);
	else rate = 3; //不指定为 3 秒
	//共享内存使⽤的变量
	buff_key = 1010;//缓冲区任给的键值
	buff_num = 1;//缓冲区任给的⻓度
	pput_key = 1020;//⽣产者放产品指针的键值
	pput_num = 1; //指针数
	shm_flg = IPC_CREAT | 0644;//共享内存读写权限
	
	//获取缓冲区使⽤的共享内存,buff_ptr 指向缓冲区⾸地址
	buff_ptr = (char *)set_shm(buff_key, buff_num, shm_flg);
	//获取⽣产者放产品位置指针 pput_ptr
	pput_ptr = (int *)set_shm(pput_key, pput_num, shm_flg);
	//信号量使⽤的变量
	prod_key = 2010;//⽣产者同步信号灯键值
	pmtx_key = 2020;//⽣产者互斥信号灯键值
	x_cons_key = 4010;//消费者同步信号灯键值
	y_cons_key = 4020;//消费者同步信号灯键值
	z_cons_key = 4030;//消费者同步信号灯键值
	cmtx_key = 4040;//消费者互斥信号灯键值
	sem_flg = IPC_CREAT | 0644;
	
	//⽣产者同步信号灯初值设为缓冲区最⼤可⽤量
	sem_val = buff_num;
	//获取⽣产者同步信号灯,引⽤标识存 
	prod_sem prod_sem = set_sem(prod_key, sem_val, sem_flg);
	
	//消费者初始⽆产品可取,同步信号灯初值设为 0
	sem_val = 0;
	//获取消费者同步信号灯,引⽤标识存 cons_sem 
	x_cons_sem = set_sem(x_cons_key, sem_val, sem_flg); 
	y_cons_sem = set_sem(y_cons_key, sem_val, sem_flg); 
	z_cons_sem = set_sem(z_cons_key, sem_val, sem_flg);
	
	//⽣产者互斥信号灯初值为 1
	sem_val = 1;
	//获取⽣产者互斥信号灯,引⽤标识存 pmtx_sem 
	pmtx_sem = set_sem(pmtx_key, sem_val, sem_flg);
	int pid=fork(); 
	if(pid<0)
	{
		printf("create fork fail"); 
		exit(1);
	}
	else if(pid==0)
	{
		while(1)
		{
			int r=rand()%3; 
			if(r==0)
			{
				//如果缓冲区满则⽣产者阻塞
				down(prod_sem);
				//如果另⼀⽣产者正在放产品,本⽣产者阻塞
				down(pmtx_sem);
				
				buff_ptr[*pput_ptr]='x'; 
				sleep(rate);
				printf("child %d producer put: %c to buffer[%d]\n",getpid(),buff_ptr[*pput_ptr],*pput_ptr);
				//唤醒阻塞的⽣产者
				up(pmtx_sem);
				//唤醒阻塞的消费者
				up(x_cons_sem);
			}
			else if(r==1)
			{
				//如果缓冲区满则⽣产者阻塞
				down(prod_sem);
				//如果另⼀⽣产者正在放产品,本⽣产者阻塞
				down(pmtx_sem); 
				 
				buff_ptr[*pput_ptr]='y';
				sleep(rate);
				printf("child %d producer put: %c to buffer[%d]\n",getpid(),buff_ptr[*pput_ptr],*pput_ptr);
				//唤醒阻塞的⽣产者
				up(pmtx_sem);
				//唤醒阻塞的消费者
				up(y_cons_sem);
			}
			else{
				//如果缓冲区满则⽣产者阻塞
				down(prod_sem);
				//如果另⼀⽣产者正在放产品,本⽣产者阻塞
				down(pmtx_sem);  
				
				buff_ptr[*pput_ptr]='z';
				sleep(rate);
				printf("child %d producer put: %c to buffer[%d]\n",getpid(),buff_ptr[*pput_ptr],*pput_ptr);
				//唤醒阻塞的⽣产者
				up(pmtx_sem);
				//唤醒阻塞的消费者
				up(z_cons_sem);
			}
		}
		return EXIT_SUCCESS;
	}
	else
	{
		while(1)
		{
			int r=rand()%3; 
			if(r==0)
			{
				//如果缓冲区满则⽣产者阻塞
				down(prod_sem);
				//如果另⼀⽣产者正在放产品,本⽣产者阻塞
				down(pmtx_sem);
				
				buff_ptr[*pput_ptr]='x'; 
				sleep(rate);
				printf("child %d producer put: %c to buffer[%d]\n",getpid(),buff_ptr[*pput_ptr],*pput_ptr);
				//唤醒阻塞的⽣产者
				up(pmtx_sem);
				//唤醒阻塞的消费者
				up(x_cons_sem);
			}
			else if(r==1)
			{
				//如果缓冲区满则⽣产者阻塞
				down(prod_sem);
				//如果另⼀⽣产者正在放产品,本⽣产者阻塞
				down(pmtx_sem); 
				 
				buff_ptr[*pput_ptr]='y';
				sleep(rate);
				printf("child %d producer put: %c to buffer[%d]\n",getpid(),buff_ptr[*pput_ptr],*pput_ptr);
				//唤醒阻塞的⽣产者
				up(pmtx_sem);
				//唤醒阻塞的消费者
				up(y_cons_sem);
			}
			else{
				//如果缓冲区满则⽣产者阻塞
				down(prod_sem);
				//如果另⼀⽣产者正在放产品,本⽣产者阻塞
				down(pmtx_sem);  
				
				buff_ptr[*pput_ptr]='z';
				sleep(rate);
				printf("child %d producer put: %c to buffer[%d]\n",getpid(),buff_ptr[*pput_ptr],*pput_ptr);
				//唤醒阻塞的⽣产者
				up(pmtx_sem);
				//唤醒阻塞的消费者
				up(z_cons_sem);
			}
		}
	}
	return EXIT_SUCCESS;
}

消费者代码

#include "ipc.h"
int get_ipc_id(char *proc_file, key_t key) {
 FILE *pf; int i, j;
 char line[BUFSZ], colum[BUFSZ];
 if ((pf = fopen(proc_file, "r")) == NULL) {
 perror("Proc file not open");
 exit(EXIT_FAILURE);
 }
 fgets(line, BUFSZ, pf);
 while (!feof(pf)) {
 i = j = 0;
 fgets(line, BUFSZ, pf);
 while (line[i] == ' ') i++;
 while (line[i] != ' ') colum[j++] = line[i++];
 colum[j] = '\0';
 if (atoi(colum) != key) continue;
 j = 0;
 while (line[i] == ' ') i++;
 while (line[i] != ' ') colum[j++] = line[i++];
 colum[j] = '\0';
 i = atoi(colum);
 fclose(pf);
 return i;
 }
 fclose(pf);
 return -1; }
/*
* 信号灯上的down/up 操作
* semid:信号灯数组标识符
* semnum:信号灯数组下标
* buf:操作信号灯的结构
*/
int down(int sem_id) {
 buf.sem_op = -1;
 buf.sem_num = 0;
 buf.sem_flg = SEM_UNDO;
 if ((semop(sem_id, &buf, 1)) < 0) {
 perror("down error ");
 exit(EXIT_FAILURE);
 }
 return EXIT_SUCCESS; }
int up(int sem_id) {
 struct sembuf buf;
 buf.sem_op = 1;
 buf.sem_num = 0;
 buf.sem_flg = SEM_UNDO;
 if ((semop(sem_id, &buf, 1)) < 0) {
 perror("up error ");
 exit(EXIT_FAILURE);
 }
 return EXIT_SUCCESS; }
/*
* set_sem 函数建⽴⼀个具有 n 个信号灯的信号量
* 如果建⽴成功,返回 ⼀个信号灯数组的标识符 sem_id
* 输⼊参数:
* sem_key 信号灯数组的键值
* sem_val 信号灯数组中信号灯的个数
* sem_flag 信号等数组的存取权限
*/
int set_sem(key_t sem_key, int sem_val, int sem_flg) {
 int sem_id;
 Sem_uns sem_arg;
 //测试由 sem_key 标识的信号灯数组是否已经建⽴
 if ((sem_id = get_ipc_id("/proc/sysvipc/sem", sem_key)) < 0 ) {
 //semget 新建⼀个信号灯,其标号返回到 sem_id
 if ((sem_id = semget(sem_key, 1, sem_flg)) < 0) {
 perror("semaphore create error");
 exit(EXIT_FAILURE);
 }
 //设置信号灯的初值sem_arg.val = sem_val;
 if (semctl(sem_id, 0, SETVAL, sem_arg) < 0) {
 perror("semaphore set error");
 exit(EXIT_FAILURE);
 }
 }
 return sem_id; }
/*
* set_shm 函数建⽴⼀个具有 n 个字节 的共享内存区
* 如果建⽴成功,返回 ⼀个指向该内存区⾸地址的指针 shm_buf
* 输⼊参数:
* shm_key 共享内存的键值
* shm_val 共享内存字节的⻓度
* shm_flag 共享内存的存取权限
*/
char *set_shm(key_t shm_key, int shm_num, int shm_flg) {
 int i, shm_id;
 char *shm_buf;
 //测试由 shm_key 标识的共享内存区是否已经建⽴
 if ((shm_id = get_ipc_id("/proc/sysvipc/shm", shm_key)) < 0 ) {
 //shmget 新建 ⼀个⻓度为 shm_num 字节的共享内存,其标号返回shm_id
 if ((shm_id = shmget(shm_key, shm_num, shm_flg)) < 0) {
 perror("shareMemory set error"); exit(EXIT_FAILURE);
 }
 //shmat 将由 shm_id 标识的共享内存附加给指针 shm_buf
 if ((shm_buf = (char *)shmat(shm_id, 0, 0)) < (char *)0) {
 perror("get shareMemory error"); exit(EXIT_FAILURE);
 }
 for (i = 0; i < shm_num; i++) shm_buf[i] = 0; //初始为 0
 }
 //shm_key 标识的共享内存区已经建⽴,将由 shm_id 标识的共享内存附加给指针 shm_buf
 if ((shm_buf = (char *)shmat(shm_id, 0, 0)) < (char *)0) {
 perror("get shareMemory error");
 exit(EXIT_FAILURE);
 }
 return shm_buf; }
/*
* set_msq 函数建⽴⼀个消息队列
* 如果建⽴成功,返回 ⼀个消息队列的标识符 msq_id
* 输⼊参数:
* msq_key 消息队列的键值
* msq_flag 消息队列的存取权限
*/
int set_msq(key_t msq_key, int msq_flg) 
{
	 int msq_id;
	 //测试由 msq_key 标识的消息队列是否已经建⽴
	 if ((msq_id = get_ipc_id("/proc/sysvipc/msg", msq_key)) < 0 ) {
	 //msgget 新建⼀个消息队列,其标号返回到 msq_id
	 if ((msq_id = msgget(msq_key, msq_flg)) < 0) {
	 perror("messageQueue set error"); exit(EXIT_FAILURE);
	 }
	 }
	 return msq_id; 
 }
int main(int argc,char *argv[])
{
	int rate;
	//可在在命令⾏第⼀参数指定⼀个进程睡眠秒数,以调解进程执⾏速度  
	if (argv[1] != NULL) rate = atoi(argv[1]);
	else rate = 3; //不指定为 3 秒
	//共享内存使⽤的变量
	buff_key = 1010;//缓冲区任给的键值
	buff_num = 1;//缓冲区任给的⻓度
	pput_key = 1020;//⽣产者放产品指针的键值
	pput_num = 1; //指针数
	shm_flg = IPC_CREAT | 0644;//共享内存读写权限
	
	//获取缓冲区使⽤的共享内存,buff_ptr 指向缓冲区⾸地址
	buff_ptr = (char *)set_shm(buff_key, buff_num, shm_flg);
	//获取⽣产者放产品位置指针 pput_ptr
	pput_ptr = (int *)set_shm(pput_key, pput_num, shm_flg);
	//信号量使⽤的变量
	prod_key = 2010;//⽣产者同步信号灯键值
	pmtx_key = 2020;//⽣产者互斥信号灯键值
	x_cons_key = 4010;//消费者同步信号灯键值
	y_cons_key = 4020;//消费者同步信号灯键值
	z_cons_key = 4030;//消费者同步信号灯键值
	cmtx_key = 4040;//消费者互斥信号灯键值
	sem_flg = IPC_CREAT | 0644;
	
	//⽣产者同步信号灯初值设为缓冲区最⼤可⽤量
	sem_val = buff_num;
	//获取⽣产者同步信号灯,引⽤标识存 
	prod_sem prod_sem = set_sem(prod_key, sem_val, sem_flg);
	
	//消费者初始⽆产品可取,同步信号灯初值设为 0
	sem_val = 0;
	//获取消费者同步信号灯,引⽤标识存 cons_sem 
	x_cons_sem = set_sem(x_cons_key, sem_val, sem_flg); 
	y_cons_sem = set_sem(y_cons_key, sem_val, sem_flg); 
	z_cons_sem = set_sem(z_cons_key, sem_val, sem_flg);
	
	//消费者互斥信号灯初值为 1
	sem_val = 1;
	//获取消费者互斥信号灯,引⽤标识存 cmtx_sem; 
	cmtx_sem = set_sem(cmtx_key, sem_val, sem_flg);
	int pid1,pid2; 
	pid1=fork(); 
	if(pid1<0)
	{
		printf("create fork pid1 fail\n"); 
		exit(1);
	}
	else if(pid1==0)
	{
		while(1){
			//若没有相应产品,消费者阻塞
			down(x_cons_sem);
			//如果另一消费者正在取产品,本消费者阻塞
			down(cmtx_sem);
			sleep(rate);
			printf("%d 进程拥有 x,得到另外两种材料,可以抽烟\n",getpid());
			//唤醒阻塞的消费者
			up(cmtx_sem);
			//唤醒阻塞的生产者
			up(prod_sem);
		}
	}
	else{
		pid2=fork(); 
		if(pid2<0)
		{
			printf("create fork pid2 fail\n"); 
			exit(1);
		}
		else if(pid2==0)
		{
			while(1)
			{
				//若没有相应产品,消费者阻塞
				//printf("%d\n",y_cons_sem); 
				down(y_cons_sem);
				//如果另一消费者正在取产品,本消费者阻塞
				//puts("234"); 
				down(cmtx_sem); 
				sleep(rate);
				printf("%d 进程拥有 y,得到另外两种材料,可以抽烟\n",getpid());
				//唤醒阻塞的消费者
				up(cmtx_sem);
				//唤醒阻塞的生产者
				up(prod_sem);
			}
		}
		else{
			while(1)
			{
			//若没有相应产品,消费者阻塞
			down(z_cons_sem);
			//如果另一消费者正在取产品,本消费者阻塞
			down(cmtx_sem);
			sleep(rate);
			printf("%d 进程拥有 z,得到另外两种材料,可以抽烟\n",getpid());
			//唤醒阻塞的消费者
			up(cmtx_sem);
			//唤醒阻塞的生产者
			up(prod_sem);
			}
		}
	}
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生产者消费者问题是一个经典的同步问题,其中生产者和消费者共享一个缓冲区,生产者向缓冲区中生产产品,消费者从缓冲区中消费产品。在多线程的环境下,生产者和消费者可能会同时访问缓冲区,因此需要对缓冲区进行同步控制。 以下是一个简单的生产者消费者问题的实现: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int count = 0; int in = 0; int out = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t empty = PTHREAD_COND_INITIALIZER; pthread_cond_t full = PTHREAD_COND_INITIALIZER; void *producer(void *arg) { int i; for (i = 0; i < 20; i++) { pthread_mutex_lock(&mutex); while (count == BUFFER_SIZE) { pthread_cond_wait(&empty, &mutex); } buffer[in] = i; in = (in + 1) % BUFFER_SIZE; count++; printf("producer: produced %d\n", i); pthread_cond_signal(&full); pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } void *consumer(void *arg) { int i, data; for (i = 0; i < 20; i++) { pthread_mutex_lock(&mutex); while (count == 0) { pthread_cond_wait(&full, &mutex); } data = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; printf("consumer: consumed %d\n", data); pthread_cond_signal(&empty); pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, producer, NULL); pthread_create(&tid2, NULL, consumer, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; } ``` 在代码中,我们定义了一个大小为10的缓冲区,使用一个计数器count来记录缓冲区中产品的数量,in和out分别表示生产者和消费者在缓冲区中的位置。我们使用了两个条件变量empty和full来控制生产者消费者的同步。 在生产者中,当缓冲区已满时,生产者会等待empty条件变量,直到缓冲区有空位。当生产者生产完一个产品后,会唤醒消费者,并释放互斥锁。 在消费者中,当缓冲区为空时,消费者会等待full条件变量,直到缓冲区有产品。当消费者消费完一个产品后,会唤醒生产者,并释放互斥锁。 通过使用互斥锁和条件变量,我们可以保证生产者和消费者的正确同步,避免了竞争条件和死锁等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值