999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

利用Linux互斥鎖解決生產者—消費者問題

2021-03-07 02:00:41趙顥凱柴玉梅
電腦知識與技術 2021年36期

趙顥凱 柴玉梅

摘要:在計算機操作系統的學習過程中,生產者—消費者問題向來是難點。結合Linux系統提供的互斥鎖機制,編寫C語言程序實現生產者—消費者問題,并對運行結果進行了詳細分析,旨在幫助學習者更好地理解該問題,為掌握其他進程同步與互斥問題奠定基礎。

關鍵詞:生產者—消費者問題;進程同步;Linux;互斥鎖

中圖分類號:TP316? ? ? ? 文獻標識碼:A

文章編號:1009-3044(2021)36-0132-03

開放科學(資源服務)標識碼(OSID):

Using Linux Mutex Mechanism to Solve Producer-consumer Problem

ZHANG Hao-kai, CHAI Yu-mei

(School of Computer and Software Engineering,University of Science and Technology Liaoning, Anshan 114051, China)

Abstract: In the process of learning computer operating system, the producer-consumer problem has always been difficult . Based on the mutex mechanism provided by Linux, a C program is written to solve the problem.And the results are analyzed in detail to help learners better understand the problem and lay? foundation for mastering other process synchronization and mutex problems.

Key words:producer-consumer problem; process synchronization; Linux; mutex

1 引言

生產者—消費者問題是操作系統中一個經典的進程同步問題。該問題是指有若干個生產者和消費者線程,連接在可數個單位緩沖區的有界環狀緩沖上,故又稱有界緩沖問題。在緩沖區內生產者線程所產生的產品不斷地被投入,只要緩沖區未空,消費者線程就會不斷地從緩沖區中取走或消費產品[1]。

在學習的過程中,筆者發現自己及周圍的很多同學對此都不甚理解。因此想借助Linux系統提供的互斥鎖機制,設計一個C語言的程序來更好地理解該問題。

2 生產者—消費者問題描述

2.1 二者的關系圖

生產者線程與消費者線程關系如圖1所示。

2.2 問題分析

生產者線程和消費者線程對緩沖區進行操作時,如果未加以限制,就會造成緩沖區結果不唯一。并且兩者的交替的執行會導致線程之間永遠的等待,造成系統出現死鎖的狀態。原因是兩者之間訪問緩沖區的速度不匹配,需要調整并發的線程的執行速度,這種關系也被叫作線程同步。

3 Linux互斥鎖解決生產者—消費者問題

3.1 涉及的函數

表1列出了解決該問題所需的Linux API[2]。

3.2 代碼實現

3.2.1 設計思路

變量P_MEMBER,C_MEMBER分別控制生產者、消費者數量,NUMBER表示緩沖區的大小,循環控制兩者對緩沖區buff的操作次數也就是局部變量j。線程對緩沖區buff[NUMBER]中的數據進行+1、-1操作。全局變量in、out則控制二者在緩沖區的位置。當生產者進行操作時,空則buff[in]+1,滿則釋放互斥鎖;消費者進行操作時,滿則buff[in]-1,空則釋放互斥鎖。

3.2.2 程序清單

#include "stdio.h"

#include "pthread.h"

pthread_cond_t g_empty = PTHREAD_COND_INITIALIZER;? ? ? ? //條件變量初始化

pthread_cond_t g_full = PTHREAD_COND_INITIALIZER;? ? ? ? ?//條件變量初始化

pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;? ? ? //互斥鎖初始化

#define P_MEMBER 3

#define C_MEMBER 1

#define NUMBER 6

int buff[NUMBER] = { 0 };? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//緩沖區大小

int producer_id = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //生產者線程ID

int customer_id = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //消費者線程ID

int in = 0;

int out = 0;

//生產者方法

void* producer()

{

int id = ++producer_id;? ? ? ? ? ? ? ? ? ? ? ? ? ?//分配生產者ID

int j = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//限制生產者操作次數

while (j < 4)

{

sleep(1);? ? ? ? ? ? ? ? ? ? ? ? &nbsp; ? ?//調節生產者消費者速度便于觀察

pthread_mutex_lock(&g_mutex);? ? ? ? ?//上鎖

in = in % NUMBER;

while (buff[in] == 1)? ? ? ? ? ? ?//緩沖區滿,釋放互斥鎖,消費者線程操作

{

printf("buff[%d] is full,producer %d is waiting for customer.\n", in, id);

pthread_cond_wait(&g_full, &g_mutex);

}

printf("producer %d put into buff[%d]. buff[%d]+1 \t\n", id, in,in);

buff[in] += 1;

in += 1;

pthread_cond_signal(&g_empty);? ? ? ? ? //生產出資源,喚醒條件變量

pthread_mutex_unlock(&g_mutex);? ? ? ? //解鎖

j++;

}

}

//消費者方法

void* customer()

{

int id = ++customer_id;? ? ? ? ? ? ? ?//分配生產者ID

int j = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ?//限制消費者操作次數

while (j < 12)

{

sleep(1);

pthread_mutex_lock(&g_mutex);

out = out % NUMBER;

while (buff[out] == 0)? ? ? ? ? //緩沖區空,釋放互斥鎖,生產者線程操作

{

printf("buff[%d] is empty,customer %d is waiting for producer\n", out, id);

pthread_cond_wait(&g_empty, &g_mutex);

}

printf("customer %id take out buff[%d]. buff[%d]-1 \t\n", id, out.out);

buff[out] -= 1;

out += 1;

pthread_cond_signal(&g_full);? ? ? ? ? //消費了資源,喚醒條件變量

pthread_mutex_unlock(&g_mutex);

j++;

}

}

int main(void)

{

int i, p_ret[P_MEMBER], c_ret[C_MEMBER];

pthread_attr_t p_attr[P_MEMBER], c_attr[C_MEMBER];? //定義生產者消費者線程

pthread_t p_tid[P_MEMBER], c_tid[C_MEMBER];? ?//初始化生產者消費者線程ID

for (i = 0;i < P_MEMBER;++i)

{

pthread_attr_init(&p_attr[i]);? ? ? ? ? ? ? ? ? ? //初始化生產者線程

pthread_attr_setdetachstate(&p_attr[i], PTHREAD_CREATE_DETACHED);

}

for (i = 0;i < C_MEMBER;++i)

{

pthread_attr_init(&c_attr[i]);? ? ? ? ? ? ? ? ? ? //初始化消費者線程

pthread_attr_setdetachstate(&c_attr[i], PTHREAD_CREATE_DETACHED);

}

//創建MEMBER個生產者線程

for (i = 0;i < P_MEMBER;++i)

{

p_ret[i] = pthread_create(&p_tid[i], &p_attr[i], producer, (void*)(&i));

if (p_ret[i] != 0)

{

printf("producer error code:%d\n", i);

}

}

//創建MEMBER個消費者線程

for (i = 0;i < C_MEMBER;++i)

{

c_ret[i] = pthread_create(&c_tid[i], &c_attr[i], customer, NULL);

if (c_ret[i] != 0)

{

printf("customer error code:%d\n", i);

}

}

pthread_exit(NULL);

}

3.3 結果分析

在VMware Workstation虛擬機中裝載的CentOS-7-64中編譯、運行該程序,某次運行的部分結果如圖2所示。

圖2中的(1)表明第一個到達的是消費者,初始時緩沖區是空的,所以customer 1要等待。隨后,陸續到達一批生產者放產品入緩沖區。當buff[0]中有產品時,會喚醒customer 1,如圖2中的(2)所示。圖2中的(3)表明當某個緩沖區位置滿時,生產者要等待,另外,還實現了多個生產者對同一個緩沖區位置的互斥訪問。圖2中的(4)和(5)則表示當消費者取走產品后,喚醒等待的生產者。

3.4 深入理解

改變生產者、消費者的數量及緩沖區的大小可以對生產者—消費者問題進行更深入的理解。

3.4.1供求基本平衡的情況

修改生產者、消費者數量為2,改變緩沖區大小為buff[4],修改每個生產者、消費者執行次數為2。某次輸出結果如圖3所示。

多次運行程序,都會得到類似的結果,因此可初步斷定供求基本平衡時,可能不會出現等待狀態。

3.4.2供大于求的情況

修改生產者數量為3,消費者數量為1,改變緩沖區大小為buff[6],修改每個生產者執行次數4、消費者執行次數為12。某次部分輸出結果如圖4所示。

多次運行程序,大都會有生產者處于等待的狀態。

3.4.3供不應求的情況

修改生產者數量為1,消費者數量為3,改變緩沖區大小為buff[3],修改每個生產者執行次數為3、消費者執行次數為1。某次部分輸出結果如圖5所示。

多次運行程序,大都會有消費者處于等待的狀態。

4 結語

本文使用Linux提供的互斥鎖機制,設計、編寫程序解決生產者—消費者問題。詳細分析了供求基本平衡、供大于求及供不應求時,生產者與消費者如何競爭、搶占和等待資源。筆者及同學們通過此程序對這個經典的進程同步問題有了更直觀?的理解。但此程序未能實現封裝,操作不便,不利于多次使用。這也是筆者下一步要解決的問題。

參考文獻:

[1] 費翔林,駱斌.操作系統教程[M].5版.北京:高等教育出版社,2014.

[2] 文全剛.嵌入式 Linux 操作系統原理與應用[M].北京:北京航天航空大學出版社,2011.

[3] Andrew S Tanenbaum.Modern Operating Systems[M]. Englewood,Pearson,2007.

[4] Randal E Bryant/David O`Hallaron.深入理解計算機[M].3版.北京:機械工業出版社,2016.

[5] 李梅.生產者-消費者的Linux多線程實現[J].價值工程,2012,31(30):221-222.

【通聯編輯:王力】

主站蜘蛛池模板: 老司机精品久久| 亚洲综合九九| 青青草原国产精品啪啪视频| 成人福利一区二区视频在线| 日韩在线2020专区| 亚洲高清资源| 无码专区国产精品一区| 狠狠色狠狠色综合久久第一次| 免费观看男人免费桶女人视频| 日本成人不卡视频| 欧美啪啪网| 99在线观看精品视频| 精品综合久久久久久97超人| 伊人久久大香线蕉影院| 欧美五月婷婷| 美女黄网十八禁免费看| 国产女人18毛片水真多1| 91无码人妻精品一区| 亚洲无码视频喷水| 亚洲码一区二区三区| 高清无码手机在线观看| 亚洲午夜国产片在线观看| 91成人免费观看在线观看| 亚洲日韩精品无码专区| 精品无码国产一区二区三区AV| 色婷婷在线播放| 国产一区二区三区在线精品专区| 国模私拍一区二区| 国产精品成人AⅤ在线一二三四| 有专无码视频| 无码AV日韩一二三区| 日韩免费毛片视频| 日本手机在线视频| 在线观看国产精品日本不卡网| 99在线视频免费| AV无码国产在线看岛国岛| 91丝袜美腿高跟国产极品老师| 亚洲Av激情网五月天| 精品亚洲麻豆1区2区3区| 国产欧美视频综合二区| 国产黄色免费看| 国产内射一区亚洲| 国产va在线| 亚洲无码熟妇人妻AV在线| 狠狠操夜夜爽| 日本尹人综合香蕉在线观看| 在线观看视频99| 国产chinese男男gay视频网| 亚洲中文字幕97久久精品少妇| 色屁屁一区二区三区视频国产| 无码啪啪精品天堂浪潮av| 免费看美女自慰的网站| 欧美自拍另类欧美综合图区| 99热最新在线| 国产香蕉在线视频| 综1合AV在线播放| 老色鬼欧美精品| a级毛片免费看| 日韩123欧美字幕| 久久精品娱乐亚洲领先| 欧美一级色视频| 六月婷婷综合| 久久精品国产一区二区小说| 蝌蚪国产精品视频第一页| 污网站在线观看视频| 九色视频一区| 2020国产精品视频| 中文字幕 91| 午夜国产理论| 久无码久无码av无码| 亚洲久悠悠色悠在线播放| 青青青伊人色综合久久| 色综合天天操| 91精品啪在线观看国产60岁 | 欧美国产精品不卡在线观看 | 中文字幕中文字字幕码一二区| AV无码无在线观看免费| 亚洲日韩久久综合中文字幕| 欧美精品成人一区二区视频一| 亚国产欧美在线人成| 久99久热只有精品国产15| 国产十八禁在线观看免费|