亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        利用Linux互斥鎖解決生產(chǎn)者—消費(fèi)者問題

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

        趙顥凱 柴玉梅

        摘要:在計(jì)算機(jī)操作系統(tǒng)的學(xué)習(xí)過程中,生產(chǎn)者—消費(fèi)者問題向來是難點(diǎn)。結(jié)合Linux系統(tǒng)提供的互斥鎖機(jī)制,編寫C語言程序?qū)崿F(xiàn)生產(chǎn)者—消費(fèi)者問題,并對運(yùn)行結(jié)果進(jìn)行了詳細(xì)分析,旨在幫助學(xué)習(xí)者更好地理解該問題,為掌握其他進(jìn)程同步與互斥問題奠定基礎(chǔ)。

        關(guān)鍵詞:生產(chǎn)者—消費(fèi)者問題;進(jìn)程同步;Linux;互斥鎖

        中圖分類號:TP316? ? ? ? 文獻(xiàn)標(biāo)識碼:A

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

        開放科學(xué)(資源服務(wù))標(biāo)識碼(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 引言

        生產(chǎn)者—消費(fèi)者問題是操作系統(tǒng)中一個(gè)經(jīng)典的進(jìn)程同步問題。該問題是指有若干個(gè)生產(chǎn)者和消費(fèi)者線程,連接在可數(shù)個(gè)單位緩沖區(qū)的有界環(huán)狀緩沖上,故又稱有界緩沖問題。在緩沖區(qū)內(nèi)生產(chǎn)者線程所產(chǎn)生的產(chǎn)品不斷地被投入,只要緩沖區(qū)未空,消費(fèi)者線程就會(huì)不斷地從緩沖區(qū)中取走或消費(fèi)產(chǎn)品[1]。

        在學(xué)習(xí)的過程中,筆者發(fā)現(xiàn)自己及周圍的很多同學(xué)對此都不甚理解。因此想借助Linux系統(tǒng)提供的互斥鎖機(jī)制,設(shè)計(jì)一個(gè)C語言的程序來更好地理解該問題。

        2 生產(chǎn)者—消費(fèi)者問題描述

        2.1 二者的關(guān)系圖

        生產(chǎn)者線程與消費(fèi)者線程關(guān)系如圖1所示。

        2.2 問題分析

        生產(chǎn)者線程和消費(fèi)者線程對緩沖區(qū)進(jìn)行操作時(shí),如果未加以限制,就會(huì)造成緩沖區(qū)結(jié)果不唯一。并且兩者的交替的執(zhí)行會(huì)導(dǎo)致線程之間永遠(yuǎn)的等待,造成系統(tǒng)出現(xiàn)死鎖的狀態(tài)。原因是兩者之間訪問緩沖區(qū)的速度不匹配,需要調(diào)整并發(fā)的線程的執(zhí)行速度,這種關(guān)系也被叫作線程同步。

        3 Linux互斥鎖解決生產(chǎn)者—消費(fèi)者問題

        3.1 涉及的函數(shù)

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

        3.2 代碼實(shí)現(xiàn)

        3.2.1 設(shè)計(jì)思路

        變量P_MEMBER,C_MEMBER分別控制生產(chǎn)者、消費(fèi)者數(shù)量,NUMBER表示緩沖區(qū)的大小,循環(huán)控制兩者對緩沖區(qū)buff的操作次數(shù)也就是局部變量j。線程對緩沖區(qū)buff[NUMBER]中的數(shù)據(jù)進(jìn)行+1、-1操作。全局變量in、out則控制二者在緩沖區(qū)的位置。當(dāng)生產(chǎn)者進(jìn)行操作時(shí),空則buff[in]+1,滿則釋放互斥鎖;消費(fèi)者進(jìn)行操作時(shí),滿則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 };? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//緩沖區(qū)大小

        int producer_id = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //生產(chǎn)者線程ID

        int customer_id = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //消費(fèi)者線程ID

        int in = 0;

        int out = 0;

        //生產(chǎn)者方法

        void* producer()

        {

        int id = ++producer_id;? ? ? ? ? ? ? ? ? ? ? ? ? ?//分配生產(chǎn)者ID

        int j = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//限制生產(chǎn)者操作次數(shù)

        while (j < 4)

        {

        sleep(1);? ? ? ? ? ? ? ? ? ? ? ? &nbsp; ? ?//調(diào)節(jié)生產(chǎn)者消費(fèi)者速度便于觀察

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

        in = in % NUMBER;

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

        {

        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);? ? ? ? ? //生產(chǎn)出資源,喚醒條件變量

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

        j++;

        }

        }

        //消費(fèi)者方法

        void* customer()

        {

        int id = ++customer_id;? ? ? ? ? ? ? ?//分配生產(chǎn)者ID

        int j = 0;? ? ? ? ? ? ? ? ? ? ? ? ? ?//限制消費(fèi)者操作次數(shù)

        while (j < 12)

        {

        sleep(1);

        pthread_mutex_lock(&g_mutex);

        out = out % NUMBER;

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

        {

        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);? ? ? ? ? //消費(fèi)了資源,喚醒條件變量

        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];? //定義生產(chǎn)者消費(fèi)者線程

        pthread_t p_tid[P_MEMBER], c_tid[C_MEMBER];? ?//初始化生產(chǎn)者消費(fèi)者線程ID

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

        {

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

        pthread_attr_setdetachstate(&p_attr[i], PTHREAD_CREATE_DETACHED);

        }

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

        {

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

        pthread_attr_setdetachstate(&c_attr[i], PTHREAD_CREATE_DETACHED);

        }

        //創(chuàng)建MEMBER個(gè)生產(chǎn)者線程

        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);

        }

        }

        //創(chuàng)建MEMBER個(gè)消費(fèi)者線程

        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 結(jié)果分析

        在VMware Workstation虛擬機(jī)中裝載的CentOS-7-64中編譯、運(yùn)行該程序,某次運(yùn)行的部分結(jié)果如圖2所示。

        圖2中的(1)表明第一個(gè)到達(dá)的是消費(fèi)者,初始時(shí)緩沖區(qū)是空的,所以customer 1要等待。隨后,陸續(xù)到達(dá)一批生產(chǎn)者放產(chǎn)品入緩沖區(qū)。當(dāng)buff[0]中有產(chǎn)品時(shí),會(huì)喚醒customer 1,如圖2中的(2)所示。圖2中的(3)表明當(dāng)某個(gè)緩沖區(qū)位置滿時(shí),生產(chǎn)者要等待,另外,還實(shí)現(xiàn)了多個(gè)生產(chǎn)者對同一個(gè)緩沖區(qū)位置的互斥訪問。圖2中的(4)和(5)則表示當(dāng)消費(fèi)者取走產(chǎn)品后,喚醒等待的生產(chǎn)者。

        3.4 深入理解

        改變生產(chǎn)者、消費(fèi)者的數(shù)量及緩沖區(qū)的大小可以對生產(chǎn)者—消費(fèi)者問題進(jìn)行更深入的理解。

        3.4.1供求基本平衡的情況

        修改生產(chǎn)者、消費(fèi)者數(shù)量為2,改變緩沖區(qū)大小為buff[4],修改每個(gè)生產(chǎn)者、消費(fèi)者執(zhí)行次數(shù)為2。某次輸出結(jié)果如圖3所示。

        多次運(yùn)行程序,都會(huì)得到類似的結(jié)果,因此可初步斷定供求基本平衡時(shí),可能不會(huì)出現(xiàn)等待狀態(tài)。

        3.4.2供大于求的情況

        修改生產(chǎn)者數(shù)量為3,消費(fèi)者數(shù)量為1,改變緩沖區(qū)大小為buff[6],修改每個(gè)生產(chǎn)者執(zhí)行次數(shù)4、消費(fèi)者執(zhí)行次數(shù)為12。某次部分輸出結(jié)果如圖4所示。

        多次運(yùn)行程序,大都會(huì)有生產(chǎn)者處于等待的狀態(tài)。

        3.4.3供不應(yīng)求的情況

        修改生產(chǎn)者數(shù)量為1,消費(fèi)者數(shù)量為3,改變緩沖區(qū)大小為buff[3],修改每個(gè)生產(chǎn)者執(zhí)行次數(shù)為3、消費(fèi)者執(zhí)行次數(shù)為1。某次部分輸出結(jié)果如圖5所示。

        多次運(yùn)行程序,大都會(huì)有消費(fèi)者處于等待的狀態(tài)。

        4 結(jié)語

        本文使用Linux提供的互斥鎖機(jī)制,設(shè)計(jì)、編寫程序解決生產(chǎn)者—消費(fèi)者問題。詳細(xì)分析了供求基本平衡、供大于求及供不應(yīng)求時(shí),生產(chǎn)者與消費(fèi)者如何競爭、搶占和等待資源。筆者及同學(xué)們通過此程序?qū)@個(gè)經(jīng)典的進(jìn)程同步問題有了更直觀?的理解。但此程序未能實(shí)現(xiàn)封裝,操作不便,不利于多次使用。這也是筆者下一步要解決的問題。

        參考文獻(xiàn):

        [1] 費(fèi)翔林,駱斌.操作系統(tǒng)教程[M].5版.北京:高等教育出版社,2014.

        [2] 文全剛.嵌入式 Linux 操作系統(tǒng)原理與應(yīng)用[M].北京:北京航天航空大學(xué)出版社,2011.

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

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

        [5] 李梅.生產(chǎn)者-消費(fèi)者的Linux多線程實(shí)現(xiàn)[J].價(jià)值工程,2012,31(30):221-222.

        【通聯(lián)編輯:王力】

        久久aⅴ无码av高潮AV喷| 国产亚洲2021成人乱码| 久久精品一区二区三区av| 女女同性黄网在线观看| 好看的国内自拍三级网站| 久久天堂精品一区二区三区四区 | 狼狼色丁香久久女婷婷综合| 乱老年女人伦免费视频| 国模少妇一区二区三区| 男人阁久久| 国产精品麻豆一区二区三区| 又大又长粗又爽又黄少妇视频| 亚洲国产成人久久一区www | 亚洲av无码男人的天堂在线| 国内精品福利在线视频| av网站不卡的av在线| 人妻洗澡被强公日日澡电影| vr成人片在线播放网站| 一区二区三区国产97| 亚洲sm另类一区二区三区| 美女被内射中出在线观看| 午夜成人理论福利片| 久久久久亚洲av无码观看| 亚洲精品美女久久久久99| 亚洲视频免费在线观看| 亚洲av无码专区在线播放| 日本成人久久| 国产黄三级三级三级三级一区二区| 激情综合五月开心婷婷| aaa级久久久精品无码片| 国产乱子伦视频一区二区三区| 青青青爽在线视频免费播放| 国产无夜激无码av毛片| 国产精品久久久久久久久KTV| 中文字幕精品永久在线| 美腿丝袜在线一区二区| 国产无遮挡无码视频免费软件| 国产精品美女黄色av| 婷婷开心五月亚洲综合| 九九久久99综合一区二区| 亚洲аv天堂无码|