1. 程式人生 > >Linux下程序的同步互斥例項——生產者消費者

Linux下程序的同步互斥例項——生產者消費者

linux下的同步和互斥

Linux sync_mutex

看的更舒服點的版本= =

Semaphore.h

一份好文件,勝讀十年書

本文參考了諸多資料,百度百科,cplusplus等

首先介紹一個頭檔案
#include <semaphore.h>

這裡麵包含了大多數的所需要使用的訊號量.
包含:

  • int sem_init(sem_t *sem, int pshared, unsigned int value)
    用於初始化訊號量。
    value代表訊號量的初始值,
    pshare代表訊號量是程序內的執行緒共享,還是程序間共享。

對於Linux而言,就是子程序共享和父程序共享——Linux中不存線上程的問題,Linux中的執行緒,程序均為程序,只是看程序組,子程序父程序而已。對於程序關係,可以使用pstree

檢視。

返回0時成功,返回-1時失敗,並且設定errno
使用perror輸出錯誤資訊:
- EINVAL
value 超過 `SEM_VALUE_MAX`
- ENOSYS
pshared 非零,但系統還沒有支援程序共享的訊號量。
  • int sem_post(sem_t *sem)
    這個函式相當於V操作,是一個"原子操作"——即是不會被打斷(中斷)的。平行計算中會出現的兩個線
    程同時對一個變數相加導致變數的值僅產生了一次變化在此處是不成立的。
    返回0時成功,返回-1時失敗, 並且設定errno:

    • EINVAL
      sem 不是一個有效的訊號量。
    • EOVERFLOW
      訊號量允許的最大值將要被超過。
  • int sem_wait(sem_t *sem)
    這個函式相當於P操作,也是一個"原子操作"。等待對變數-1,如果不能對變數-1,則進入等待佇列

  • int sem_trywait(sem_t *sem)
    如果變數不能-1(即sem_t為0),則不會進入等待佇列,直接返回錯誤程式碼。
  • int sem_timedwait(sem_t *sem)
  • int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
    • return 0 (success), return -1 (failure) and set errno:
      • EINTR
        The call was interrupted by a signal handler; see signal(7).
        //呼叫被訊號處理中斷
      • EINVAL sem is not a valid semaphore.
          //sem不是有效的訊號量
        The following additional error can occur for sem_trywait():
          //下面的錯誤是sem_trywait()可能發生的:
      • EAGAIN The operation could not be performed without blocking (i.e., the
          semaphore currently has the value zero).
          //除了鎖定無法進行別的操作(如訊號量當前是0值).
        The following additional errors can occur for sem_timedwait():
          //下面的錯誤是sem_timedwait()可能發生的:
      • EINVAL The value of abs_timeout.tv_nsecs is less than 0, or greater than or
          equal to 1000 million.
          //abs_timeout.tv_nsecs 的值比0小或者大於等於1000毫秒(譯者注:納秒的值不能比0小,不能比1秒大)
      • ETIMEDOUT
          The call timed out before the semaphore could be locked.
          //在訊號量鎖定之前就超時了
      • 注意
        對這些函式,訊號處理程式總是會中斷阻塞,不管是否使用了sigaction(2)的SA_RESTART標誌位.

  1. /*=============================================================================
  2. #
  3. # Author: svtter - [email protected]
  4. #
  5. # QQ : 57180160
  6. #
  7. # Last modified: 2014-10-03 20:35
  8. #
  9. # Filename: producer_consumer.cc
  10. #
  11. # Description:
  12. #
  13. =============================================================================*/
  14. #include<cstdio>
  15. #include<unistd.h>
  16. #include<semaphore.h>
  17. #include<pthread.h>
  18. #include<sys/types.h>
  19. #include<stdlib.h>
  20. #include<iostream>
  21. usingnamespace std;
  22. #define N 5
  23. #define item int
  24. // P/V操作
  25. void P(sem_t* sem)
  26. {
  27. if(sem_wait(sem))
  28. perror("P error!");
  29. }
  30. void V(sem_t* sem)
  31. {
  32. if(sem_post(sem))
  33. perror("V error!");
  34. }
  35. sem_t mutex;
  36. sem_t full;
  37. sem_t empty;
  38. item buffer[N];
  39. int i =0, j =-1;
  40. void init_sem()
  41. {
  42. sem_init(&mutex,0,1);
  43. sem_init(&full,0,0);
  44. sem_init(&empty,0, N);
  45. }
  46. void* producer(void*arg)
  47. {
  48. int product;
  49. while(1)
  50. {
  51. //生成隨機數字
  52. product = rand()%100;
  53. // cout << "producer running..." << endl;
  54. P(&empty);
  55. P(&mutex);
  56. buffer[i]= product;
  57. printf("producer produced %d @ %d pos\n",
  58. product, i);
  59. i=(i+1)%N;
  60. V(&mutex);
  61. V(&full);
  62. sleep(1);
  63. }
  64. }
  65. void* consumer(void*arg)
  66. {
  67. int product, temp;
  68. while(1)
  69. {
  70. // cout << "consumer running..." << endl;
  71. P(&full);
  72. P(&mutex);
  73. j =(j+1)%N;
  74. product = buffer[j];
  75. V(&mutex);
  76. V(&empty);
  77. printf("Consumer consumed %d @ %d pos\n",
  78. product, j);
  79. sleep(3);
  80. }
  81. }
  82. int main()
  83. {
  84. //random num
  85. srand(time(NULL));
  86. init_sem();
  87. int error;
  88. pthread_tproducer_t,consumer_t;
  89. error = pthread_create(&producer_t, NULL, producer, NULL);
  90. if(error !=0)
  91. printf("error in create producer.\n");
  92. else
  93. printf("create producer success!\n");
  94. pthread_create(&consumer_t, NULL, consumer, NULL);
  95. if(error !=0)
  96. printf("error in create consumer.\n");
  97. else
  98. printf("create consumer success!\n");
  99. pthread_join(producer_t, NULL);
  100. pthread_join(consumer_t, NULL);
  101. return0;
  102. }

相關推薦

Linux程序同步互斥例項——生產者消費者

linux下的同步和互斥 Linux sync_mutex 看的更舒服點的版本= = Semaphore.h 一份好文件,勝讀十年書 本文參考了諸多資料,百度百科,cplusplus等 首

Linux多執行緒模擬生產者/消費者問題

/*用執行緒的同步和互斥來實現"生產者-消費者"問題.*/ /* 多生產者多消費者多緩衝區 生產者和消費者不可同時進行 */ #include <stdio.h> #include <stdlib.h> //#include <unistd.h

程序同步互斥經典題之消費者生產者問題

問題背景:有兩個程序分別為消費者程序和生產者程序,對同一個臨界資源進行訪問,生產者不斷地將生產的產品加入快取區,而消費者不斷地消費快取區中的資源,利用訊號量實現兩個程序的同步和互斥。 問題分析:在生產者往快取區中加入產品的時候,需要兩個訊號量,一個是互斥訊號量,使得在生產者

經典程序同步互斥問題——生產者消費者問題

問題描述:生產者——消費者問題是指有兩組程序共享一個環形的緩衝池,一組稱為生產者,一組稱為消費者。緩衝池是由若干個大小相等的緩衝區組成,每個緩衝區可以容納一個產品。生產者程序不斷的將產品放入緩衝池中,消費者不斷將產品從緩衝池中取出。核心:生產者——消費者問題,既存在著程序同步

經典程序同步問題:生產者-消費者問題

1.生產者-消費者問題   假定在生產者和消費者之間的公用緩衝池中具有n個緩衝區,消費者不能同時取一個緩衝區的產品,生產者不能同時向同一個緩衝區放入產品。只有緩衝區中有產品時,消費者才可以取產品,只有緩衝區有空時,生產者才可以放入產品。消費者與生產者也不能同時對同一個緩衝區進行操作

程序互斥控制_消費者生產者經典問題

題目: 假定在生產者和消費者之間的公用緩衝池中具有n個緩衝區,消費者不能同時取一個緩衝區的產品,生產者不能同時向同一個緩衝區放入產品。只有緩衝區中有產品時,消費者才可以取產品,只有緩衝區有空時,生產者才可以放入產品。消費者與生產者也不能同時對同一個緩衝區進行操作。 程式碼: 訊號量的設定

Linux Pipe (程序間通訊,生產者消費者

PIPE是Linux下可以用來實現程序間通訊的一種手段,當我們呼叫pipe系統呼叫時,將會產生一對檔案描述符,fd[0]可以用來讀,fd[1]用來寫,fd[1]寫的資料將會在fd[0]中讀到,我們稱之為管道。程序之間可以依賴管道的方式實現程序間通訊,pipe是半

Linux程序間通訊與生產者消費者問題

生產者消費者問題(英語:Producer-consumerproblem),也稱有限緩衝問題(英語:Bounded-bufferproblem),是一個多執行緒同步問題的經典案例。該問題描述了兩個共享固定大小緩衝區的執行緒——即所謂的“生產者”和“消費者”——在實際執行時會

Linux FIFO (程序間通訊,生產者消費者

上一篇中我們寫到了PIPE無名管道,的確是一種很方便的通訊機制,但是其有一個缺點就是,PIPE是依賴於檔案描述符的,並不在檔案系統中維護,如果兩個通訊程序之間沒有共同的祖先,他們就無法拿到相同的檔案表項,所以沒有共同祖先的兩個程序是不能通過PIPE直接通訊的。為

linux程序JDBC連接不到mysql數據庫

var 進入 日誌 啟動報錯 span -- start -s 啟動mysql   今天在linux下部署一個 JavaEE項目的時候總是連接不到Mysql數據庫,檢查之後發現連接池的配置確定是對的,進入linux服務器之後以mysql -uname -ppassword連

Linux程序的總結(3)

程序的控制 1.程序的建立 fork()函式 在一個程式碼段中建立一個新的子程序可以使用fork()函式。 1.fork()函式以父程序為模板創建出了一個子程序,但是父子程序程式碼共享,資料獨有一份。也就是分配新的記憶體塊和核心資料結構。然後父程序的部分資料拷貝到了子程序。

Linux程序的總結(2)

程的優先順序 由於每個程序的任務所要消耗的資源量不同。所以要對程序進行分級制度。 為什麼要有程序的優先順序? 計算機只有一個cpu,採用了分時機制,讓每個程式在cpu上執行很短的時間。這個時間非常短,人的感知無法仔細的觀察到。切換時間片的時候,有的程序需要緊急處理,有的程序可以放

Linux程序知識(1)

#Linux 下程序的總結(1) ##什麼是程序? 程序是程式執行一次的過程。它佔用了CPU,佔用了記憶體的資源。 作業系統為了將各個程序統一管理起來。將每一個程序定義成了一個小塊,這個小塊被稱之為PCB(Program control blocks) 程式控制塊。通常情況下我們可以

作業系統(8)程序--同步互斥介紹;同步問題的三種解決方案:禁用硬體中斷、基於軟體、更高階抽象

文章目錄 1. 背景 2. 同步問題的一個例子 3. 同步問題的初步解決方案 1. 方法一 禁用硬體中斷 2. 方法二 基於軟體的同步辦法 3. 方法三 更高階的抽象方法

Linux程序間通訊方式 - UNIX Domain Socket

概述 Linux下程序通訊方式有很多,比較典型的有套接字,平時比較常用的套接字是基於TCP/IP協議的,適用於兩臺不同主機上兩個程序間通訊, 通訊之前需要指定IP地址. 但是如果同一臺主機上兩個程序間通訊用套接字,還需要指定ip地址,有點過於繁瑣. 這個時候就需要用到UNIX Domain Sock

linux程序、以及程序間的通訊機制

2.1程序基本概念         程序是Linux事務管理的基本單元,所有的程序均擁有自己獨立的處理環境和系統資源。程序的環境由當前系統狀態及其父程序資訊決定和組成。系統的第一個程序init由核心產生,以後所有的程序都是

linux 檔案同步函式(fflush、sync、fsync、fdatasync)之間差異

遇到機器異常關機時,寫log檔案資訊丟失問題,所以記錄下。   Linux實現中在核心設有緩衝區快取記憶體或頁面快取記憶體,大多數磁碟I/O都通過緩衝區進行。當我們向檔案寫資料時,核心通常先將資料複製到一個緩衝區中,如果該緩衝區尚未寫滿,則並不將其排入輸出佇列,而是等待寫滿或者核心需要重用該

linux主從同步和redis的用法

mariadb其實就是mysql mysql已經被oracle收購,它即將閉源,馬上要開始收費了因此還想免費試用開源的資料庫mysql,就在centos7上,將mysql分支為mariadb 安裝mariadb,在centos7底下:linux軟體包的格式 mysql.rpm 1.通過yum去安裝 1

Linux配置LAMP架構例項(建立論壇)

LAMP (Web應用軟體組合) Linux+Apache+Mysql/MariaDB+Perl/PHP/Python一組常用來搭建動態網站或者伺服器的開源軟體,本身都是各自獨立的程式,但是因為常被放在一起使用,擁有了越來越高的相容度,共同組成了一個強大的Web應用程式平臺。隨著開源潮流

Python多程序,同步互斥,訊號量,鎖補充上一篇文章

from multiprocessing import Event,Process from time import sleep def wait_event1(): print("1想操作臨界區資源") e.wait() print("1開始操作臨界區資源",e.is_set()