实验四 进程同步与通信

目录

一、生产者消费者问题

代码1:

运行结果:

 二、进程间的通信——软中断实现

代码2:

 输出结果:

参考资料:


一、生产者消费者问题

代码1:

        因为Linux系统中gcc编译环境下会发生内置函数找不到的错误,且生产者消费者问题是用线程实现的,所以这里的代码直接写在Windows操作系统的Dev C++中实现。

#include 
#include 
#include 
#include 
#include 

#define N 10			 //缓冲区的大小
#define SleepTime 3		 //生产者消费者操作完后的暂停时间
typedef int semaphore;	 //定义信号量的类型均为整数
typedef char element;	 //定义生产者生产的元素都是字符
element buffer[N] = {0}; //定义长度为 N 的缓冲区,内容均是字符型
int in = 0;				 //缓冲区下一个存放产品的索引
int out = 0;			 //缓冲区下一个可以使用的产品索引
double StartTime;		 //程序开始时间记录,方便输出执行语句的时间

semaphore mutex = 1, empty = N, full = 0;

//生产者线程
void *Producer(void *args)
{
	int *x = (int *)args;
	element eletemp;
	int sum = 0;
	while (sum < 10)
	{
		while (empty <= 0) //P(empty),判断是否有空位置供存放生产的产品,同步,没有空位则等待并输出提示语句
			printf("%.4lfs| 缓 冲 区 已 满 ! 生 产 者 :%d 等待中......\n", (clock() - StartTime) / CLOCKS_PER_SEC, *x);
		empty--;		   //等到一个空位置,先把他占用
		while (mutex <= 0) //P(mutex),判断当前临界区中是否有进程正在生产或者消费,如果有则等待并输出提示语句
			printf("%.4lfs|	缓冲区有进程正在操作 !	生产者 :%d 等待中......\n", (clock() - StartTime) / CLOCKS_PER_SEC, *x);
		mutex--;					  //等到占用进程出临界区,进入临界区并占用
		eletemp = (rand() % 26) + 65; //生产一个产品,即任意产生一个 A~Z 的字母
		//输出生产成功的字样
		printf("%.4lfs| 生产者: %d 生产一个产品: %c ,并将其放入缓冲区: %d 位置\n", (clock() - StartTime) / CLOCKS_PER_SEC, *x, eletemp, in);
		buffer[in] = eletemp; //将生产的产品存入缓冲区
		sum++;
		in = (in + 1) % N; //缓冲区索引更新
		mutex++;		   //V(mutex),临界区使用完成释放信号
		full++;			   //V(full),实现同步,释放 full
		sleep(SleepTime);  //当前生产者生产完成,休眠一定时间才能继续
	}
}

//消费者线程
void *Consumer(void *args)
{
	int *x = (int *)args;
	int sum = 0;
	while (sum < 10)
	{
		while (full <= 0) //P(full),判断缓冲区当中是否有产品可以消费,同步如果没有产品则等待同时输出提示语句
			printf("%.4lfs| \t\t\t\t\t\t\t 缓冲区为空!消费者: %d 等待中......\n", (clock() - StartTime) / CLOCKS_PER_SEC, *x);

		full--; //等到有一个产品,消费这个产品

		while (mutex <= 0) //P(mutex),判断临界区是否有进程在处理,如果有则等待并输出提示语句
			printf("%.4lfs| \t\t\t\t\t\t\t 缓冲区有进程正在操作! 消费者 : %d 等待中......\n", (clock() - StartTime) / CLOCKS_PER_SEC, *x);

		mutex--; //等到临界区为空,则进入缓冲区消费
		//输出消费成功的语句
		printf("%.4lfs| \t\t\t\t\t\t\t 消费者: %d 消费一个产品: %c , 产品位于位于缓冲区 : %d 位置 \n", (clock() - StartTime) / CLOCKS_PER_SEC, *x, buffer[out], out);
		buffer[out] = 0; //更新缓冲区,把消费掉的产品清空
		sum++;
		out = (out + 1) % N; //更新缓冲区索引
		mutex++;			 //消费完成退出缓冲区,释放资源
		empty++;			 //消费完成产生一个空位,进行同步
		sleep(SleepTime);	 //当前消费者消费了一个产品,休眠一段时间再继续
	}
}


int main()
{
	//记录程序开始的时间,方便记录消费者和生产者活动的时间
	StartTime = clock();
	//产生随机种子,生产的时候随机生产一个字符
	srand((int)time(NULL));
	printf(" 时间");
	printf("    \t\t 生产者动态显示");
	printf("          \t\t\t\t 消费者动态显示\n");
	printf("======================================================================================================================\n");
	//定义一个线程数组,存储所有的消费者和生产者线程
	pthread_t threadPool[2];

	int t1=1;
	pthread_create(&threadPool[0], NULL, Producer, (void *)&t1);
	pthread_create(&threadPool[1], NULL, Consumer, (void *)&t1);

	void *result;
	for (int i = 0; i < 2; i++) //等待线程结束并回收资源,线程之间同步
	{
		if (pthread_join(threadPool[i], &result) == -1)
		{
			printf("fail to recollect\n"); //进程回收,如果回收失败输出错误提示
			exit(1);					   //结束线程
		}
	}
}

运行结果:

实验四 进程同步与通信_第1张图片

实验四 进程同步与通信_第2张图片

 二、进程间的通信——软中断实现

代码2:

实验四 进程同步与通信_第3张图片

 

 输出结果:

实验四 进程同步与通信_第4张图片

参考资料:

(4条消息) 操作系统实验三——生产者-消费者问题_Luobuda的博客-CSDN博客_操作系统生产者消费者问题流程图https://blog.csdn.net/weixin_44668030/article/details/110291203?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165249565416782248588195%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165249565416782248588195&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-110291203-null-null.142%5Ev9%5Econtrol,157%5Ev4%5Econtrol&utm_term=%E7%94%9F%E4%BA%A7%E8%80%85%E6%B6%88%E8%B4%B9%E8%80%85%E9%97%AE%E9%A2%98&spm=1018.2226.3001.4187(4条消息) Linux signal()和kill()_OLLEH~的博客-CSDN博客_kill函数和signal函数的使用方法https://blog.csdn.net/qq_44198589/article/details/110206494

你可能感兴趣的