程序間通訊 訊號量 互斥鎖等的異同

2021-06-20 05:08:47 字數 2728 閱讀 8199

程序間通訊——訊號量、互斥鎖等的異同

最早接觸在系統上程式設計,是在嵌入式linux上完成幾項功能。當時就是按照寫微控制器程式的思維寫的。實現幾個功能,就用了乙個程序,單執行緒來做。

後來實習時,接觸linux下多程序,多執行緒的程式設計。了解到多個執行緒之間的操作需要進行同步,互斥等。

在工作後,有進行了ucos的多工程式設計。發現ucos中的多工的同步,互斥與linux下有很多相似性。但是也有很多不同。

也因為一開始把ucos的訊號量,互斥鎖等和linux模擬來操作。概念確實是一致的,但是由於具體實現的差異,也導致了實際操作中的一些失誤(ucos中的任務相當於程序中的執行緒,任務間通訊相當於執行緒間通訊)。

雖然,經過這些實踐,但是有些疑問卻一直沒有解開。

在一篇部落格中到關於深入了解系統的書籍推薦找到了《unix網路程式設計第二卷:程序間通訊》,說道它介紹了訊號量等ipc通訊(但是它也說了,這些技術是老掉牙的技術)。

不過這本書確實解開了不少一直來的疑惑。

傳統設計原則認為:把應用程式設計為一組互相通訊的小片段比將其設計為單個龐大的程式更好。

應用程式的幾種構建方法:

1、用乙個龐大的程式完成全部工作。

2、使用多個程式,程式之間用某種形式的ipc進行通訊;

3、使用乙個包含多個執行緒的程式,執行緒之間使用某種ipc。

注:ipc:interprocess communication,程序間通訊。

在自己最早的時候使用的就是第一種方式來構建程式的。

對於unpv2,主要介紹了4種不同的ipc方式:

1、訊息傳遞;

2、同步(互斥量、條件變數、讀寫鎖、檔案和記錄鎖、訊號量);

3、共享記憶體;

4、遠端過程呼叫。

由於更多的是在單程序中實現多執行緒通訊,對於同步的使用要多於訊息傳遞。因為在單程序中,所有執行緒共享執行位址空間。全域性變數(以及區域性靜態變數(通過訪問函式))所有執行緒可以訪問。所以對於同步的使用要多於訊息傳遞。也因此對於互斥量,訊號量,條件變數等何時使用,如何使用留下了疑問。

一開始,自己把互斥鎖和訊號量幾乎沒有怎麼區分,只要實現了對臨界區的保護就可以。也感覺他們之間似乎沒什麼差異,還納悶為什麼會有了互斥鎖還有訊號量存在。

在已經有了互斥鎖的時候,還提供訊號量,posix.1給出的理由是:提供訊號量的主要目的是提供一種程序間同步方式。這些程序可能共享也可能不共享記憶體區。互斥鎖,條件變數是作為執行緒間同步機制說明的,這些執行緒總是共享某個記憶體區(因為執行緒共享執行位址空間)。這兩者都是已經廣泛用了很多年的同步正規化。每組原語都特別適合於特定的問題。

應該可以理解為,互斥鎖,條件變數,訊號量都可以作為同步來使用,不必糾結於需要同步時使用那乙個。但是每乙個都用了很長時間,都有自己特別適合的問題。所以就都留著了。

也就因為有自己最合適的問題,所以它們之間肯定有些地方很不一樣。

以下是:訊號量,互斥鎖,條件變數三者的一些差別:

1、互斥鎖總是要由給它上鎖的執行緒解鎖,訊號量的掛出卻不必由執行過它的等待操作的統一執行緒執行。

2、互斥鎖要麼被鎖住,要麼被解開(二值狀態,類似於二值訊號量,區別於多值訊號量)。

3、既然訊號量有乙個與之關聯的狀態(它的計數值),那麼訊號量掛出操作總是被記住。而當向乙個條件變數傳送訊號時,如果沒有執行緒等待在蓋條件變數,則該訊號丟失。(即:如果在訊號量掛出的時候,沒有執行緒等待此訊號量,則在下次有執行緒等待的時候,會收到此訊號量,並進行處理。而條件變數則將會陷入等待)

4、在posix.1標準中,各種同步技巧(互斥鎖,條件變數,讀寫鎖,訊號量)中,只有訊號量掛出操作,能夠在訊號處理程式中安全呼叫。

從這幾點看,似乎訊號量很有優勢,但也因為功能強大,所以其執行開銷會偏大。具體的效能,需要實際在系統中測試才知道。

unpv2在最後關於解決問題使用哪種ipc給出的解答是:對於解決特定問題使用哪種ipc,應該視具體問題而定。我們可以做的是,熟悉各種ipc機制,然後根據具體需要選擇乙個適合當前的。

關於訊息傳遞一塊,個人感覺:遠端過程呼叫和共享記憶體,都是實現了一種訊息傳遞的方式,或者更準確的說是資料傳遞。雖然對於具體實現技術上來說,有四種ipc方式,但是從資料傳遞和同步來看,只有兩種。一種實現臨界區保護,一種實現資訊的傳遞。

在ucos中也有一些對應於這些ipc方式的實現(當然是任務間通訊):

1、訊息傳遞(郵箱,訊息佇列);

3、同步(訊號量,互斥鎖,郵箱(可以作為互斥來用));

由於ucos中的**,共享記憶體空間,所以全域性變數就相當於記憶體共享。所以在使用ucos的時候,更多的參照執行緒間通訊的方式,來操作。但是就像文前提到的,ucos畢竟不遵守posix.1標準,所以在實現上不一樣。

在linux上訊號量很多時候是二值訊號量(不知道最新的是否支援多值),但是ucos支援的訊號量是多值訊號量。由於一開始將ucos上的訊號量模擬於linux上的訊號量,也當做二值來處理,結果程式的執行結果不符合預期。

雖然很多概念是適用的,但是當針對於具體應用的時候,還是要看具體的實現是怎麼樣子的。這樣才會避免一些細節上的問題。而且對於嵌入式程式設計而言,ipc技術不但不是老掉牙的技術,相反還是十分重要的。因為嵌入式開發中,有時候使用的作業系統,是共享位址空間的。而且有時候,要實現多工,多執行緒等同步操作就是其中實現任務或者執行緒間協作的很重要的乙個步驟。即使開發裸機系統,出去效能考慮會實現為非同步式的。而非同步就要考慮很多資源的同步問題,其實也就是做乙個作業系統的一些工作——排程。

由於現在linux等作業系統對於這些高度抽象,似乎不用去考慮這些。但是對於嵌入式程式設計而言,這些還是要經常面對的問題。

ipc對於嵌入式開發,還不過時。

注:技術員技術練級攻略

《unpv2》

《嵌入式實時作業系統μc/os-2》

程序間通訊 訊號量

ipc識別符號和關鍵字 在終端輸入ipcs,可以看到目前系統中所有的ipc資訊 第一列的key就是ipc的關鍵字,第二列是ipc的識別符號。ftok 函式用於獲得乙個ipc的關鍵字,其函式原型是 key t ftok const char pathname,int proj id 下面是乙個訊號量的...

程序間通訊 訊號量

system ipc中,對於每乙個新建的訊號量 訊息佇列 共享記憶體,都有乙個在整個系統中唯一的識別符號。每個標識也都有唯一對應的關鍵字,關鍵字的資料型別為ket t 在終端輸入命令 ipcs 可以看到目前系統中所有的ipc資訊 共享記憶體段 鍵 shmid 擁有者 許可權 位元組 nattch 狀...

程序間通訊 訊號量

訊號量不是ipc 機構,它只是乙個計數器用於不同程序之間或同一程序不同執行緒之間的同步,型別 二元訊號 值為0或 1,1說明有可用資源,0說明此時資源占用,其他程序需等待。計數訊號量 表示可用資源數量。計數訊號量集 由乙個或多個訊號量組成的集合,每乙個都是計數訊號量。訊號量資料結構 include ...