亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Linux服務器 > 正文

淺談生產者消費者模型(Linux系統下的兩種實現方法)

2024-09-05 23:03:28
字體:
來源:轉載
供稿:網友

生產者消費者問題是同步問題中的一種常見情況,借用一下維基百科的話

生產者消費者問題(英語:Producer-consumer problem),也稱有限緩沖問題(英語:Bounded-buffer problem),是一個多線程同步問題的經典案例。該問題描述了兩個共享固定大小緩沖區的線程——即所謂的“生產者”和“消費者”——在實際運行時會發生的問題。生產者的主要作用是生成一定量的數據放到緩沖區中,然后重復此過程。與此同時,消費者也在緩沖區消耗這些數據。該問題的關鍵就是要保證生產者不會在緩沖區滿時加入數據,消費者也不會在緩沖區中空時消耗數據。

第一種實現信號量配合互斥鎖實現,這種方法很清晰簡單

信號量:

信號量的特性如下:信號量是一個非負整數(車位數),所有通過它的線程/進程(車輛)都會將該整數減一(通過它當然是為了使用資源),當該整數值為零時,所有試圖通過它的線程都將處于等待狀態。在信號量上我們定義兩種操作: Wait(等待) 和 Release(釋放)。當一個線程調用Wait操作時,它要么得到資源然后將信號量減一,要么一直等下去(指放入阻塞隊列),直到信號量大于等于一時。Release(釋放)實際上是在信號量上執行加操作,對應于車輛離開停車場,該操作之所以叫做“釋放”是因為釋放了由信號量守護的資源。

wait, release在Linux下

int sem_wait(sem_t * sem);
int sem_post(sem_t * sem);

設定兩個信號量,empty用來表示空槽的個數,full用來表示占有的個數

生產者在向任務隊列里放資源時,調用sem_wait(&full)來檢查隊列是否已滿,如果滿的話,就阻塞,直到有消費者從里面取資源再蘇醒,如果不滿,就放資源,并通知消費者來取。

消費者在從任務隊列里取資源時,調用sem_wait(&empty)來檢查隊列是否為空,如果空的話,就阻塞,直到有生產者向里面放資源再蘇醒,如果不空,就取資源,并通知生產者來放。

而互斥鎖僅僅是為了防止多個線程同時對隊列進行操作,造成未知的結果。

#include <stdio.h>#include <pthread.h>#include <semaphore.h>#define MAX 5 //隊列長度pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;sem_t full; 	//填充的個數sem_t empty; 	//空槽的個數int top = 0;   //隊尾int bottom = 0; //隊頭void* produce(void* arg){	int i;	for ( i = 0; i < MAX*2; i++)	{		printf("producer is preparing data/n");		sem_wait(&empty);//若空槽個數低于0阻塞				pthread_mutex_lock(&mutex);				top = (top+1) % MAX;		printf("now top is %d/n", top);		pthread_mutex_unlock(&mutex);				sem_post(&full);	}	return (void*)1;}void* consume(void* arg){	int i;	for ( i = 0; i < MAX*2; i++)	{		printf("consumer is preparing data/n");		sem_wait(&full);//若填充個數低于0阻塞			pthread_mutex_lock(&mutex);				bottom = (bottom+1) % MAX;		printf("now bottom is %d/n", bottom);		pthread_mutex_unlock(&mutex);				sem_post(&empty);	}	return (void*)2;}int main(int argc, char *argv[]){	pthread_t thid1;	pthread_t thid2;	pthread_t thid3;	pthread_t thid4;	int ret1;	int ret2;	int ret3;	int ret4;	sem_init(&full, 0, 0);	sem_init(&empty, 0, MAX);	pthread_create(&thid1, NULL, produce, NULL);	pthread_create(&thid2, NULL, consume, NULL);	pthread_create(&thid3, NULL, produce, NULL);	pthread_create(&thid4, NULL, consume, NULL);	pthread_join(thid1, (void**)&ret1);	pthread_join(thid2, (void**)&ret2);	pthread_join(thid3, (void**)&ret3);	pthread_join(thid4, (void**)&ret4);	return 0;}

注:如果把sem_wait()和sem_post()放到pthread_mutex_lock()與pthread_mutex_unlock()之間會如何呢?

答案是:死鎖,因為我們不能預知線程進入共享區順序,如果消費者線程先對mutex加鎖,并進入,sem_wait()發現隊列為空,阻塞,而生產者在對mutex加鎖時,發現已上鎖也阻塞,雙方永遠無法喚醒對方。

第二種是條件變量配合互斥鎖實現

條件變量的常見用法是在不滿足某些條件時,阻塞自己,直到有線程通知自己醒來。

而互斥量在這里的作用依然還是防止多線程對共享資源同時操作,造成未知結果。

生產者消費者的行為與之前相同,只不過原來只調用sem_wait()可以完成兩步,1是檢查條件,2是阻塞,現在條件變量需要我們自己來設定條件(所以說條件變量配合互斥鎖比信號量的功能更強大,因為它可以自定義休眠條件,但是這對使用者的要求也提高了,必須理清邏輯關系避免死鎖)

#include <stdio.h>#include <pthread.h>#define MAX 5pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t notfull = PTHREAD_COND_INITIALIZER; 	//是否隊滿pthread_cond_t notempty = PTHREAD_COND_INITIALIZER; 	//是否隊空int top = 0;int bottom = 0;void* produce(void* arg){	int i;	for ( i = 0; i < MAX*2; i++)	{		pthread_mutex_lock(&mutex);		while ((top+1)%MAX == bottom)		{			printf("full! producer is waiting/n");			pthread_cond_wait(¬full, &mutex);//等待隊不滿		}		top = (top+1) % MAX;		printf("now top is %d/n", top);		pthread_cond_signal(¬empty);//發出隊非空的消息		pthread_mutex_unlock(&mutex);	}	return (void*)1;}void* consume(void* arg){	int i;	for ( i = 0; i < MAX*2; i++)	{		pthread_mutex_lock(&mutex);		while ( top%MAX == bottom)		{			printf("empty! consumer is waiting/n");			pthread_cond_wait(¬empty, &mutex);//等待隊不空		}		bottom = (bottom+1) % MAX;		printf("now bottom is %d/n", bottom);		pthread_cond_signal(¬full);//發出隊不滿的消息		pthread_mutex_unlock(&mutex);	}	return (void*)2;}int main(int argc, char *argv[]){	pthread_t thid1;	pthread_t thid2;	pthread_t thid3;	pthread_t thid4;	int ret1;	int ret2;	int ret3;	int ret4;	pthread_create(&thid1, NULL, produce, NULL);	pthread_create(&thid2, NULL, consume, NULL);	pthread_create(&thid3, NULL, produce, NULL);	pthread_create(&thid4, NULL, consume, NULL);	pthread_join(thid1, (void**)&ret1);	pthread_join(thid2, (void**)&ret2);	pthread_join(thid3, (void**)&ret3);	pthread_join(thid4, (void**)&ret4);	return 0;}

注:

為什么信號量在互斥區外,而條件變量在互斥區內呢?

因為互斥鎖本質上是二元信號量,和信號量互斥的原理相同,而且放在互斥區會死鎖,而條件變量是和互斥鎖協同配合的,

我們從pthread_cond_wait()和pthread_cond_signal()的內部實現就可以看出

pthread_cond_wait()是先將互斥鎖解開,并陷入阻塞,直到pthread_signal()發出信號后pthread_cond_wait()再加上鎖,然后退出,可以看到它們在設計時就是為了協同配合,而互斥鎖和信號量都是由Linux下的futex機制實現的,這里就不展開說了

這里貼出了pthread_wait()源碼圖

生產者消費者模型

以上就是小編為大家帶來的淺談生產者消費者模型(Linux系統下的兩種實現方法)全部內容了,希望大家多多支持VEVB武林網~

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色悠久久久久综合先锋影音下载| 国产精品成人一区| 欧美色道久久88综合亚洲精品| 日本国产欧美一区二区三区| 国产精品一区二区三区免费视频| 亚洲人成伊人成综合网久久久| 欧美日韩国产黄| 欧美—级a级欧美特级ar全黄| 久久久久久中文字幕| 亚洲精品视频网上网址在线观看| 成人免费淫片aa视频免费| 亚洲精品国产精品自产a区红杏吧| 国产精品久久久久久久电影| 亚洲精品国产拍免费91在线| 在线免费观看羞羞视频一区二区| 国产在线久久久| 国产91精品高潮白浆喷水| 韩国v欧美v日本v亚洲| 激情久久av一区av二区av三区| 国产精品自拍视频| 色综合色综合网色综合| 国产精品视频白浆免费视频| 亚洲一区二区三区毛片| 日韩福利在线播放| 日本久久久久亚洲中字幕| 国产成人在线亚洲欧美| 一区二区三区回区在观看免费视频| www.国产精品一二区| 日韩成人激情影院| 97在线精品视频| 亚洲国产成人在线播放| xvideos成人免费中文版| 久久人91精品久久久久久不卡| 欧美激情啊啊啊| 久久精品国产综合| 色悠悠久久88| 韩日精品中文字幕| 欧美成人h版在线观看| 亚洲综合av影视| 亚洲最大福利视频网| 97久久精品在线| 色婷婷**av毛片一区| 最近2019中文字幕在线高清| 欧美丰满老妇厨房牲生活| 亚洲欧美另类中文字幕| 一本色道久久综合亚洲精品小说| 欧美国产第二页| 亚洲欧洲av一区二区| 国产在线视频91| 91影院在线免费观看视频| 精品日本美女福利在线观看| 欧美国产日产韩国视频| 成人国产精品色哟哟| 久久精品中文字幕电影| 亚洲欧美另类国产| 26uuu国产精品视频| 久久久免费高清电视剧观看| 国产偷亚洲偷欧美偷精品| 国产午夜精品一区理论片飘花| 久久免费精品日本久久中文字幕| 国产亚洲精品激情久久| 久久6精品影院| 久久久噜久噜久久综合| 九色成人免费视频| 欧美精品电影免费在线观看| 欧美综合在线第二页| 岛国av一区二区在线在线观看| x99av成人免费| 插插插亚洲综合网| 日韩美女免费视频| 久久亚洲综合国产精品99麻豆精品福利| 国产精品免费一区二区三区都可以| 精品久久久久久久久久ntr影视| 欧美一级电影在线| 国产专区精品视频| 亚洲国产成人久久综合| 欧美成人三级视频网站| 亚洲国产成人在线播放| 亚洲黄页网在线观看| 国产69精品久久久久99| 欧美日韩亚洲国产一区| 日韩在线欧美在线国产在线| 国产精品毛片a∨一区二区三区|国| 正在播放欧美视频| 在线观看中文字幕亚洲| 自拍视频国产精品| 精品国产91久久久久久老师| 中文字幕亚洲欧美一区二区三区| 欧美成人在线影院| 日本久久精品视频| 这里只有精品久久| 国产精品专区一| 国产v综合v亚洲欧美久久| 91精品视频一区| 亚洲成人精品视频在线观看| 不卡伊人av在线播放| 亚洲欧美在线第一页| 91精品在线影院| 91精品国产沙发| 国产精品久久久久久婷婷天堂| 国产欧美精品xxxx另类| 欧美视频在线视频| 久久色免费在线视频| 亚洲视频网站在线观看| 亚洲欧美国产一区二区三区| 国产一区二区三区在线播放免费观看| 久久久久日韩精品久久久男男| 久久人人爽人人爽人人片av高清| 欧美激情视频在线免费观看 欧美视频免费一| 中文字幕亚洲天堂| 91精品国产沙发| 国产欧美最新羞羞视频在线观看| 久久久久久国产精品久久| 久久久亚洲国产天美传媒修理工| 成人a在线观看| 久久成年人免费电影| 国产日韩欧美在线播放| 欧美日韩亚洲一区二区| 91性高湖久久久久久久久_久久99| 国产视频精品在线| 日韩av成人在线| 日韩成人av一区| 国产精品美女视频网站| 亚洲欧美日韩网| 精品国产乱码久久久久久虫虫漫画| 这里只有精品视频在线| 国产成+人+综合+亚洲欧美丁香花| 欧美激情一区二区久久久| 俺去了亚洲欧美日韩| 久久久久久久久久久亚洲| 国产美女精品视频免费观看| 91精品国产综合久久男男| 久久噜噜噜精品国产亚洲综合| 国产色婷婷国产综合在线理论片a| 国产色婷婷国产综合在线理论片a| 国产伦精品一区二区三区精品视频| 亚洲成人在线视频播放| 欧美日韩免费区域视频在线观看| 欧美成人精品在线视频| 在线日韩av观看| 2021久久精品国产99国产精品| 91亚洲va在线va天堂va国| 性欧美暴力猛交69hd| 国产精品观看在线亚洲人成网| 亚洲视频在线观看| 91久久久久久久| 国产精品精品视频一区二区三区| 久久精品久久久久久| 亚洲激情视频在线播放| 欧美成人免费一级人片100| 成人精品视频99在线观看免费| 国产69精品99久久久久久宅男| 日韩av电影在线免费播放| 久久99久久亚洲国产| 国产在线98福利播放视频| 欧美午夜美女看片| 亚洲福利视频在线| 最近2019年手机中文字幕| 亚洲最大福利网站| 欧美日韩国产色视频| 亚洲日韩欧美视频一区| 57pao精品| 91夜夜未满十八勿入爽爽影院| 久久久这里只有精品视频|