當前位置:網站首頁>實驗四 進程同步與通信

實驗四 進程同步與通信

2022-05-14 21:36:40代碼騎士

目錄

一、生產者消費者問題

代碼1:

運行結果:

 二、進程間的通信——軟中斷實現

代碼2:

 輸出結果:

參考資料:


一、生產者消費者問題

代碼1:

        因為Linux系統中gcc編譯環境下會發生內置函數找不到的錯誤,且生產者消費者問題是用線程實現的,所以這裏的代碼直接寫在Windows操作系統的Dev C++中實現。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

#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);					   //結束線程
		}
	}
}

運行結果:

 二、進程間的通信——軟中斷實現

代碼2:

 

 輸出結果:

參考資料:

(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

版權聲明
本文為[代碼騎士]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/134/202205141819289043.html

隨機推薦