操 作 系 統(tǒng) 實(shí) 驗(yàn) 報 告 課程名稱
操作系統(tǒng)
實(shí)驗(yàn)名稱
進(jìn)程(線程)的同步與互斥
成績
學(xué)生姓名
作業(yè)君
專業(yè)
軟件工程
班級、學(xué)號
同組者姓名
無
實(shí)驗(yàn)日期
2020
一、實(shí)驗(yàn)題目: : 進(jìn)程(線程)的同步與互斥 二、實(shí)驗(yàn)?zāi)康?:
自行編制模擬程序,通過形象化的狀態(tài)顯示,加深理解進(jìn)程的概念、進(jìn)程之間的狀態(tài)轉(zhuǎn)換及其所帶來的 PCB 內(nèi)容 、組織的變化,理解進(jìn)程與其 PCB 間的一一對應(yīng)關(guān)系。
1.掌握基本的同步與互斥算法,理解生產(chǎn)者消費(fèi)者模型。
2.學(xué)習(xí)使用 Windows 中基本的同步對象,掌握相關(guān) API 的使用方法。
3.了解 Windows 中多線程的并發(fā)執(zhí)行機(jī)制,實(shí)現(xiàn)進(jìn)程的同步與互斥 三、實(shí)驗(yàn)內(nèi)容與要求 :
1.實(shí)驗(yàn)內(nèi)容 以生產(chǎn)者/消費(fèi)者模型為依據(jù),在 Windows 環(huán)境下創(chuàng)建一個控制臺進(jìn)程,在該進(jìn)程中創(chuàng)建 n 個線程模擬生產(chǎn)者和消費(fèi)者,實(shí)現(xiàn)進(jìn)程(線程)的同步與互斥。
2.實(shí)驗(yàn)要求 學(xué)習(xí)并理解生產(chǎn)者/消費(fèi)者模型及其同步/互斥規(guī)則; 學(xué)習(xí)了解 Windows 同步對象及其特性; 熟悉實(shí)驗(yàn)環(huán)境,掌握相關(guān) API 的使用方法; 設(shè)計程序,實(shí)現(xiàn)生產(chǎn)者/消費(fèi)者進(jìn)程(線程)的同步與互斥;
四、算法描述(含數(shù)據(jù)結(jié)構(gòu)定義)或流程圖
#include <Windows.h> #include <iostream> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;
#define MAX_THREAD_NUM 64
//最大線程數(shù) #define INTE_PER_SEC 1000
//延遲時間的毫秒值 const int SIZE_OF_BUFFER = 10;
//緩沖區(qū)長度 int ProductID = 0;
//產(chǎn)品號 int ConsumeID = 0;
//將被消耗的產(chǎn)品號 int in = 0;
//產(chǎn)品進(jìn)緩沖區(qū)時的緩沖區(qū)下標(biāo) int out = 0;
//產(chǎn)品出緩沖區(qū)時的緩沖區(qū)下標(biāo) bool running = true;
//判斷程序能否繼續(xù)執(zhí)行的邏輯值 int g_buffer[SIZE_OF_BUFFER];
//緩沖區(qū)是個循環(huán)隊(duì)列 HANDLE g_hMutex;
//公有信號量,用于線程間的互斥 HANDLE g_hFullSemaphore;
//生產(chǎn)者的私有信號量,當(dāng)緩沖區(qū)滿時迫使生產(chǎn)者等待 HANDLE g_hEmptySemaphore;
//消費(fèi)者的私有信號量,當(dāng)緩沖區(qū)空時迫使消費(fèi)者等待
//定義一個結(jié)構(gòu)體用于存儲線程的信息 struct ThreadInfo {
int serial;
//線程號
char entity;
//線程類別(生產(chǎn)者或消費(fèi)者)
double delay;
//等待時間
double persist; //操作時間 };
//生產(chǎn)者 void Producer(void* p) {
//定義變量用于存儲當(dāng)前線程的信息
DWORD m_delay;
DWORD m_persist;
int m_serial;
//從參數(shù)中獲得信息
m_serial = ((ThreadInfo*)(p))->serial;
m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC);
m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC);
while (running)
{
//P 操作
cout << "生產(chǎn)者線程 " << m_serial << " 請求生產(chǎn)." << endl;
WaitForSingleObject(g_hEmptySemaphore, INFINITE);
cout << "生產(chǎn)者線程 " << m_serial << " 請求獨(dú)占緩沖區(qū)." << endl;
WaitForSingleObject(g_hMutex, INFINITE);
Sleep(m_delay);
//延遲等待
//生產(chǎn)一個產(chǎn)品
cout << "生產(chǎn)者線程 " << m_serial << " 生產(chǎn) " << ++ProductID << " 號產(chǎn)品成功." << endl;
cout << "生產(chǎn)者線程 " << m_serial << " 請求將產(chǎn)品 " << ProductID << " 投入緩沖區(qū)." << endl;
//把新生產(chǎn)的產(chǎn)品放入緩沖區(qū)
g_buffer[in] = ProductID;
in = (in +1)%SIZE_OF_BUFFER;
Sleep(m_persist);
//操作等待
cout << "生產(chǎn)者線程 " << m_serial << " 將產(chǎn)品 " << ProductID << " 投入緩沖區(qū)中成功." << endl;
//輸出緩沖區(qū)當(dāng)前的狀態(tài)
cout << "****************************" << endl
<< "\n 當(dāng)前緩沖區(qū)情況如圖(■代表已有產(chǎn)品,□代表沒有產(chǎn)品):
" << endl;
for (int i = 0;i < SIZE_OF_BUFFER;++i)
{
if (g_buffer[i] != 0)
cout << "■";
else
cout << "□";
}
cout << "\n\n****************************\n" << endl;
//V 操作
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullSemaphore, 1, NULL);
} }
//消費(fèi)者 void Consumer(void* p) {
DWORD m_delay;
DWORD m_persist;
int m_serial;
//從參數(shù)中獲得信息
m_serial = ((ThreadInfo*)(p))->serial;
m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC);
m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC);
while (running)
{
//P 操作
cout << "消費(fèi)者線程 " << m_serial << " 請求消費(fèi)." << endl;
WaitForSingleObject(g_hFullSemaphore, INFINITE);
cout << "消費(fèi)者線程 " << m_serial << " 請求獨(dú)占緩沖區(qū)." << endl;
WaitForSingleObject(g_hMutex,INFINITE);
Sleep(m_delay); //延遲等待
//從緩沖區(qū)中取出一個產(chǎn)品
cout << "消費(fèi)者線程 " << m_serial << " 請求取出一個產(chǎn)品." << endl;
ConsumeID = g_buffer[out];
g_buffer[out] = 0;
out = (out + 1) % SIZE_OF_BUFFER;
cout << "消費(fèi)者線程 " << m_serial << " 取出產(chǎn)品 " << ConsumeID << " 成功." << endl;
//消耗一個產(chǎn)品
cout << "消費(fèi)者線程 " << m_serial << " 開始消費(fèi)消費(fèi)產(chǎn)品 " << ConsumeID << "." << endl;
Sleep(m_persist);
cout << "消費(fèi)者線程 " << m_serial << " 消費(fèi)產(chǎn)品 " << ConsumeID << " 成功." << endl;
//輸出緩沖區(qū)當(dāng)前的狀態(tài)
cout << "****************************" << endl
<< "\n 當(dāng)前緩沖區(qū)情況如圖:
" << endl;
for (int i = 0;i < SIZE_OF_BUFFER;++i)
{
if (g_buffer[i] != 0)
cout << "■";
else
cout << "□";
}
cout << "\n\n****************************\n" << endl;
//V 操作
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);
} }
void prod_cons() {
//創(chuàng)建互斥信號量
g_hMutex = CreateMutex(NULL, FALSE, NULL);
//創(chuàng)建同步信號量
g_hEmptySemaphore = CreateSemaphore(NULL, SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);
g_hFullSemaphore = CreateSemaphore(NULL, 0, SIZE_OF_BUFFER, NULL);
srand((unsigned)time(NULL));
//以時間函數(shù)為種子
const unsigned short THREADS_COUNT = rand() % 5 + 5; //總的線程數(shù)(隨機(jī)生成)
//線程對象的數(shù)組
HANDLE hThreads[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];
DWORD thread_ID; //線程 ID
int num = 0;
//臨時變量,用于循環(huán)語句
cout << "系統(tǒng)開始模擬,并自動生成模擬數(shù)據(jù)..." << endl;
system("pause"); //暫停確認(rèn)開始執(zhí)行
cout << "線程總數(shù):" << THREADS_COUNT << endl;
//循環(huán)隨機(jī)生成各個線程的信息
while (num != THREADS_COUNT)
{
thread_info[num].serial = num + 1;
if (rand() % 2 == 1)
thread_info[num].entity = "P";
else
thread_info[num].entity = "C";
thread_info[num].delay = rand() % 5 + 1;
thread_info[num].persist = rand() % 6 + 2;
num++;
}
cout << "\n 系統(tǒng)生成數(shù)據(jù)結(jié)束,模擬數(shù)據(jù)如下:" << endl
<< "線程號
線程類別
延遲時間
操作時間" << endl;
for (int x = 0;x < THREADS_COUNT;x++)
cout << "
" << thread_info[x].serial << "\t"
<< "
" << thread_info[x].entity << "\t"
<< "
" << thread_info[x].delay << "\t\t"
<< "
" << thread_info[x].persist << endl;
cout << "\n\n==================生產(chǎn)者-消費(fèi)者 開始==================\n" << endl;
//創(chuàng)建線程
for (int i = 0;i < THREADS_COUNT;i++)
{
//創(chuàng)建生產(chǎn)者線程
if (thread_info[i].entity == "P")
hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), &thread_info[i], 0, &thread_ID);
//創(chuàng)建消費(fèi)者線程
else
hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), &thread_info[i], 0, &thread_ID);
}
while (running)
{
if (getchar())
{
//按回車后終止程序運(yùn)行
running = false;
}
}
cout << "系統(tǒng)模擬結(jié)束..." << endl; } int main() {
cout << "\n==================生產(chǎn)者-消費(fèi)者 模擬==================\n" << endl;
prod_cons(); }
五、實(shí)驗(yàn)過程
1、記錄生產(chǎn)者和消費(fèi)者的同步執(zhí)行過程。
2、分析 Producer 函數(shù)和 Consumer 函數(shù)的功能,并畫出對應(yīng)的程序流程圖。
Producer 函數(shù):調(diào)用函數(shù),獲取資源情況,然后判斷條件是否滿足,判斷是否執(zhí)行,接著發(fā)出生產(chǎn)請求,請求通過后獨(dú)占緩沖區(qū)資源,接著生產(chǎn)-一個產(chǎn)品投入緩沖區(qū),成功后釋放所占緩沖區(qū)資源,到此此函數(shù)執(zhí)行完成。
consumer 函數(shù):
通過用變量提取保存提取當(dāng)前資源信息, 然后判斷是否執(zhí)行, 接著發(fā)出消費(fèi)請求, 請求通過后獨(dú)占緩沖區(qū)資源, 接著消費(fèi)一個產(chǎn)品取出緩沖區(qū), 成功后釋放所占緩沖區(qū)資源, 到此此函數(shù)執(zhí)行完成。
3、試將同步和互斥的 P 操作顛倒次序執(zhí)行,觀察并分析程序的運(yùn)行情況。
答:
如將同步和互斥的 P 操作顛倒次序執(zhí)行,程序會產(chǎn)生死鎖。因?yàn)檫@個操作會先獨(dú)占緩沖區(qū)的資源,然后才發(fā)送請求。如果生產(chǎn)或者消費(fèi)請求無法通過而一直等待下去的話,則無法釋放資源,進(jìn)而產(chǎn)生程序的死鎖,使得程序無法運(yùn)行!
六、實(shí)驗(yàn)總結(jié)
通過本次實(shí)驗(yàn),讓我對線程的同步與互斥技術(shù)有了比較深刻的了解,生產(chǎn)者消費(fèi)者問題是研究多線線程程序繞不開的問題,它的描述是有一塊生產(chǎn)者和消費(fèi)者共享的有界緩沖區(qū),生產(chǎn)者往緩沖區(qū)放入產(chǎn)品,消費(fèi)者從緩沖區(qū)取走產(chǎn)品,這個過程可以無休止的進(jìn)行,不能因緩沖區(qū)滿生產(chǎn)者放不進(jìn)產(chǎn)品而終止,也不能因緩沖區(qū)空消費(fèi)者無產(chǎn)品可取而終止。
推薦訪問: 線程 進(jìn)程 同步在偉大祖國73華誕之際,我參加了單位組織的“光影鑄魂”主題黨日活動,集中觀看了抗美援朝題材影片《長津湖》,再一次重溫這段悲壯歷史,再一次深刻感悟偉大抗美援朝精神。1950年10月,新中國剛剛成立一年,
根據(jù)省局黨組《關(guān)于舉辦習(xí)近平談治國理政(第四卷)讀書班的通知》要求,我中心通過專題學(xué)習(xí)、專題研討以及交流分享等形式,系統(tǒng)的對《習(xí)近平談治國理政》(第四卷)進(jìn)行了深入的學(xué)習(xí)與交流,下面我就來談一談我個人
《習(xí)近平談治國理政》(第四卷)是在百年變局和世紀(jì)疫情相互疊加的大背景下,對以習(xí)近平同志為核心的黨中央治國理政重大戰(zhàn)略部署、重大理論創(chuàng)造、重大思想引領(lǐng)的系統(tǒng)呈現(xiàn)。它生動記錄了新一代黨中央領(lǐng)導(dǎo)集體統(tǒng)籌兩個
《真抓實(shí)干做好新發(fā)展階段“三農(nóng)工作”》是《習(xí)近平談治國理政》第四卷中的文章,這是習(xí)近平總書記在2020年12月28日中央農(nóng)村工作會議上的集體學(xué)習(xí)時的講話。文章指出,我常講,領(lǐng)導(dǎo)干部要胸懷黨和國家工作大
在《習(xí)近平談治國理政》第四卷中,習(xí)近平總書記強(qiáng)調(diào),江山就是人民,人民就是江山,打江山、守江山,守的是人民的心。從嘉興南湖中駛出的小小紅船,到世界上最大的執(zhí)政黨,在中國共產(chǎn)黨的字典里,“人民”一詞從來都
黨的十八大以來,習(xí)近平總書記以馬克思主義戰(zhàn)略家的博大胸襟和深謀遠(yuǎn)慮,在治國理政和推動全球治理中牢固樹立戰(zhàn)略意識,在不同場合多次圍繞戰(zhàn)略策略的重要性,戰(zhàn)略和策略的關(guān)系,提高戰(zhàn)略思維、堅定戰(zhàn)略自信、強(qiáng)化戰(zhàn)
《習(xí)近平談治國理政》第四卷集中展示了以習(xí)近平同志為核心的黨中央在百年變局和世紀(jì)疫情相互疊加背景下,如何更好地堅持和發(fā)展中國特色社會主義而進(jìn)行的生動實(shí)踐與理論探索;對于新時代堅持和發(fā)展什么樣的中國特色社
在黨組織的關(guān)懷下,我有幸參加了區(qū)委組織部組織的入黨積極分子培訓(xùn)班。為期一周的學(xué)習(xí),學(xué)習(xí)形式多樣,課程內(nèi)容豐富,各位專家的講解細(xì)致精彩,對于我加深對黨的創(chuàng)新理論的認(rèn)識、對黨的歷史的深入了解、對中共黨員的
《習(xí)近平談治國理政》第四卷《共建網(wǎng)上美好精神家園》一文中指出:網(wǎng)絡(luò)玩命是新形勢下社會文明的重要內(nèi)容,是建設(shè)網(wǎng)絡(luò)強(qiáng)國的重要領(lǐng)域。截至2021年12月,我國網(wǎng)民規(guī)模達(dá)10 32億,較2020年12月增長4
剛剛召開的中國共產(chǎn)黨第十九屆中央委員會第七次全體會議上討論并通過了黨的十九屆中央委員會向中國共產(chǎn)黨第二十次全國代表大會的報告、黨的十九屆中央紀(jì)律檢查委員會向中國共產(chǎn)黨第二十次全國代表大會的工作報告和《