日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 系统应用编程——多线程经典问题(生产者-消费者)

發(fā)布時(shí)間:2023/12/9 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 系统应用编程——多线程经典问题(生产者-消费者) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?“生產(chǎn)者——消費(fèi)者”問題是Linux多線程編程中的經(jīng)典問題,主要是利用信號(hào)量處理線程間的同步和互斥問題。

? ? ? ? ?“生產(chǎn)者——消費(fèi)者”問題描述如下:

? ? ? ? ? 有一個(gè)有限緩沖區(qū)(這里用有名管道實(shí)現(xiàn) FIFO 式緩沖區(qū))和兩個(gè)線程:生產(chǎn)者和消費(fèi)者,它們分別不停地把產(chǎn)品放入緩沖區(qū)中拿走產(chǎn)品。一個(gè)生產(chǎn)者在緩沖區(qū)滿的時(shí)候必須等待,一個(gè)消費(fèi)者在緩沖區(qū)空的時(shí)候也不IXUS等待。另外,因?yàn)榫彌_區(qū)是臨界資源,所以生產(chǎn)者和消費(fèi)者之間必須互斥進(jìn)行。它們之間的關(guān)系如下:


這里要求使用有名管道來模擬有限緩沖區(qū),并用信號(hào)量來解決“生產(chǎn)者——消費(fèi)者”問題中的同步和互斥問題。


1、信號(hào)量分析

? ? ? ? 這里使用3個(gè)信號(hào)量,其中兩個(gè)信號(hào)量 avail 和 full 分別用于解決生產(chǎn)者和消費(fèi)者線程之間的互斥問題。其中avail 表示緩沖區(qū)的空單元數(shù),初始值為N;full 表示緩沖區(qū)非空單元數(shù),初始值為 0 ; mutex 是互斥信號(hào)量 ,初始值為 1(當(dāng)然也可以用互斥鎖來實(shí)現(xiàn)互斥操作)。

2、畫出流程圖


3、編寫代碼

? ? ? ? 本實(shí)驗(yàn)的代碼中緩沖區(qū)擁有3個(gè)單元,每個(gè)單元為5個(gè)字節(jié)。為了盡量體現(xiàn)每個(gè)信號(hào)量的意義,在程序中生產(chǎn)過程和消費(fèi)過程是隨機(jī)(采取0~5s 的隨機(jī)事件間隔)進(jìn)行的,而且生產(chǎn)者的速度比消費(fèi)者的速度平均快兩倍左右。生產(chǎn)者一次生產(chǎn)一個(gè)單元的產(chǎn)品(放入hello字符串),消費(fèi)者一次消費(fèi)一個(gè)單元的產(chǎn)品。

[cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<string.h>??
  • #include?<unistd.h>??
  • #include?<pthread.h>??
  • #include?<sys/types.h>??
  • #include?<time.h>??
  • #include?<fcntl.h>??
  • #include?<semaphore.h>??
  • #include?<sys/ipc.h>??
  • #include?<errno.h>??
  • #define?MYFIFO?"myfifo"??
  • #define?BUFFER_SIZE?3??
  • #define?UNIT_SIZE?5??
  • #define?RUN_TIME?30??
  • #define?DELAY_TIME_LEVELS?5.0??
  • ??
  • void?*producer(void?*arg);??
  • void?*customer(void?*arg);??
  • ??
  • int?fd;??
  • time_t?end_time;??
  • sem_t?mutex,full,avail;??
  • ??
  • int?main()??
  • {??
  • ????int?ret;??
  • ????pthread_t?thrd_prd_id,thrd_cst_id;??
  • ??
  • ????srand(time(NULL));??
  • ????end_time?=?time(NULL)?+?RUN_TIME;??
  • ??
  • ????????/*創(chuàng)建有名管道*/??
  • ????if((mkfifo(MYFIFO,0644)?<?0)?&&?(errno?!=?EEXIST))??
  • ????{??
  • ????????perror("mkfifo?error!");??
  • ????????exit(-1);??
  • ????}??
  • ??
  • ????????/*打開管道*/??
  • ????fd?=?open(MYFIFO,O_RDWR);??
  • ????if(fd?==?-1)??
  • ????{??
  • ????????perror("open?fifo?error");??
  • ????????exit(-1);??
  • ????}??
  • ??
  • ????????/*初始化互斥信號(hào)量為1*/??
  • ????ret?=?sem_init(&mutex,0,1);??
  • ????????/*初始化avail信號(hào)量為?N?*/??
  • ????ret?+=?sem_init(&avail,0,BUFFER_SIZE);??
  • ????/*初始化full信號(hào)量為0*/??
  • ????ret?+=?sem_init(&full,0,0);??
  • ??
  • ????if(ret?!=?0)??
  • ????{??
  • ????????perror("sem_init?error");??
  • ????????exit(-1);??
  • ????}??
  • ??
  • ????????/*創(chuàng)建兩個(gè)線程*/??
  • ????ret?=?pthread_create(&thrd_prd_id,NULL,producer,NULL);??
  • ????if(ret?!=?0)??
  • ????{??
  • ????????perror("producer?pthread_create?error");??
  • ????????exit(-1);??
  • ????}??
  • ??
  • ????ret?=?pthread_create(&thrd_cst_id,NULL,customer,NULL);??
  • ????if(ret?!=?0)??
  • ????{??
  • ????????perror("customer?pthread_create?error");??
  • ????????exit(-1);??
  • ????}??
  • ??
  • ????pthread_join(thrd_prd_id,NULL);??
  • ????pthread_join(thrd_cst_id,NULL);??
  • ????close(fd);??
  • ????unlink(MYFIFO);??
  • ??
  • ????return?0;??
  • }??
  • ??
  • void?*producer(void?*arg)?//生產(chǎn)者線程??
  • {??
  • ????int?real_write;??
  • ????int?delay_time;??
  • ??
  • ????while(time(NULL)?<?end_time)??
  • ????{??
  • ????????delay_time?=?(int)(rand()?*?DELAY_TIME_LEVELS/RAND_MAX/2.0)?+?1;??
  • ????????sleep(delay_time);??
  • ??
  • ????????????????/*P操作信號(hào)量avail和mutex*/??
  • ????????sem_wait(&avail);??
  • ????????sem_wait(&mutex);??
  • ????????printf("\nproducer?have?delayed?%d?seconds\n",delay_time);??
  • ??
  • ????????????????/*生產(chǎn)者寫入數(shù)據(jù)*/??
  • ????????if((real_write?=?write(fd,"hello",UNIT_SIZE))?==?-1)??
  • ????????{??
  • ????????????if(errno?==?EAGAIN)??
  • ????????????{??
  • ????????????????printf("The?buffer?is?full,please?wait?for?reading!\n");??
  • ????????????}??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????printf("producer?writes?%d?bytes?to?the?FIFO\n",real_write);??????????
  • ????????????printf("Now,the?buffer?left?%d?spaces!\n",avail);??
  • ????????}??
  • ????????????????/*V操作信號(hào)量full?和?mutex*/??
  • ????????sem_post(&full);??
  • ????????sem_post(&mutex);??
  • ????}??
  • ????pthread_exit(NULL);??
  • }??
  • ??
  • void?*customer(void?*arg)?//消費(fèi)者線程??
  • {??
  • ????unsigned?char?read_buffer[UNIT_SIZE];??
  • ????int?real_read;??
  • ????int?delay_time;??
  • ??
  • ????while(time(NULL)?<?end_time)??
  • ????{??
  • ????????delay_time?=?(int)(rand()?*?DELAY_TIME_LEVELS/RAND_MAX/2.0)?+?1;??
  • ????????sleep(delay_time);??
  • ??
  • ????????sem_wait(&full);?//P操作信號(hào)量full和mutex??
  • ????????sem_wait(&mutex);??
  • ????????memset(read_buffer,0,UNIT_SIZE);??
  • ????????printf("\nCustomer?have?delayed?%d?seconds\n",delay_time);??
  • ??
  • ????????if((real_read?=?read(fd,read_buffer,UNIT_SIZE))?==?-1)??
  • ????????{??
  • ????????????if(errno?==?EAGAIN)??
  • ????????????{??
  • ????????????????printf("The?buffer?is?empty,please?wait?for?writing!\n");??
  • ????????????}??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????printf("customer?reads?%d?bytes?from?the?FIFO\n",real_read);??????????
  • ????????}??
  • ??
  • ????????sem_post(&avail);?//V操作信號(hào)量?avail?和?mutex??
  • ????????sem_post(&mutex);?????????
  • ????}??
  • ??
  • ????pthread_exit(NULL);??
  • }??

  • 執(zhí)行結(jié)果如下:

    [cpp]?view plaincopy
  • fs@ubuntu:~/qiang/pthread$?./cust_prod???
  • ??
  • producer?have?delayed?2?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?2?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?2?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?3?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?3?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?1?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • Customer?have?delayed?1?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?3?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?1?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?2?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?1?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?2?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?1?spaces!??
  • ??
  • Customer?have?delayed?3?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • Customer?have?delayed?1?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?3?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • producer?have?delayed?1?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?1?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • Customer?have?delayed?1?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?3?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • ??
  • Customer?have?delayed?2?seconds??
  • customer?reads?5?bytes?from?the?FIFO??
  • ??
  • producer?have?delayed?2?seconds??
  • producer?writes?5?bytes?to?the?FIFO??
  • Now,the?buffer?left?2?spaces!??
  • fs@ubuntu:~/qiang/pthread$ ?
  • 總結(jié)

    以上是生活随笔為你收集整理的Linux 系统应用编程——多线程经典问题(生产者-消费者)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。