Linux 程序通訊之 訊號和訊號量總結

2021-09-06 16:59:30 字數 4971 閱讀 2420

如今最經常使用的程序間通訊的方式有:訊號,訊號量,訊息佇列,共享記憶體。

所謂程序通訊,就是不同程序之間進行一些"接觸",這種接觸有簡單,也有複雜。機制不同,複雜度也不一樣。通訊是乙個廣義上的意義,不僅僅指傳遞一些massege。他們的用法是基本相同的,所以僅僅要掌握了一種的用法,然後記住其他的用法就能夠了。

1. 訊號

在我學習的內容中,主要接觸了訊號來實現同步的機制,據說訊號也能夠用來做其他的事

情,可是我還不知道做什麼。

訊號和訊號量是不同的,他們儘管都可用來實現同步和相互排斥,但前者是使用訊號處理器來

進行的,後者是使用p,v*作來實現的。

使用訊號要先知道有哪些訊號,在linux下有31個須要記住的通用訊號,據說也是system

v中最經常使用的那些。這裡略。

1. 1訊號相關函式:

#include

int sigaction(int signo, const struct sigaction *act, struct sigaction

*oact);

該函式用來為程序安裝訊號處理器,struct sigaction資料是用來儲存訊號處理器的相

關資訊。

#include

int sigemptyset(sigset_t *set);

將訊號集合清空。

int sigfillset(sigset_t *set);

將訊號集合設定成包括全部的訊號。在對訊號進行*作曾經一定要對訊號集進行初始化。

int sigaddset(sigset_t *set, int signo);

向訊號集中加入signo相應的新訊號。

int sigdelset(sigset_t *set, int signo);

從訊號集中刪除signo相應的乙個訊號。

int sigismember(const sigset_t *set, int signo);

推斷某個訊號是否在訊號集中。返回1則在,0則不在。

#include

int sigprocmask(int how,const sigset_t *set, sigset_t *oset);

用來設定程序的訊號遮蔽碼。訊號遮蔽碼能夠用來在某段時間內堵塞一些訊號集中的信

號,假設訊號不在訊號集中,就不必討論它,由於肯定不響應,能否生成也不肯定,我

沒有做過試驗。

1.2我所理解的使用訊號機制的方法:

使用訊號,主要做的事情就是訊號處理器的工作,這裡面是你想做的事情。就像中斷處理

函式一樣。

在使用訊號曾經,首先要初始化訊號集,僅僅有在訊號集裡面的訊號才會被考慮。

有兩種方法能夠初始化訊號集,一種是設定空訊號集,一種是將全部的訊號都加到訊號集

中。假設你自己想要的訊號集不是這兩種,能夠在初始化了以後通過加入和刪除訊號進行

定製。

假設在程序執行的一段時間內不想對某些訊號進行響應,則能夠使用sigprocmask對當前

的訊號集中的一些訊號進行堵塞,稍後再執行。

當你將訊號集設定完成後,在讓他工作之前須要安裝訊號處理器。安裝訊號處理器能夠實

現這幾個功能:

指定訊號處理函式的入口;指定訊號遮蔽集合;指定訊號處理器的一些標誌。所謂訊號處

理器,就是指定了一些處理方法,關鍵在於安裝訊號處理器,這是使正確的訊號進行正確

的處理關鍵。在安裝的時候,一定要對特定的訊號賦予正確的訊號處理函式。

我不知道不同程序之間的訊號處理器能否混用,可是像乙個特定的程序中有多少個訊號處

理器這種問題是不能提的。由於訊號處理器是乙個概念,他針對的是訊號,就是說假設

你指定了乙個資料結構,用它來儲存針對某個訊號的處理資訊,那麼安裝訊號處理器就是

賦予這個資料結構一些相關資訊,使用訊號處理器就是用這個資料結構儲存的資訊來組織

一種機制當發生這個訊號的時候會做一些你實現設定好的處理。可是假設區分不同程序中

對同乙個訊號的不同處理器?我想處理器可能僅僅對核它所屬的程序有關的訊號進行響應,

可是假設是這種話,那這是怎麼實現的呢?

只是有一點是能夠知道的,那就是每個訊號都有乙個訊號處理器(確定的),能夠動過

安裝訊號處理器來指定她的行為。訊號處理器由他自己的資訊儲存區域(我不知道在什麼

地方),可是能夠通過向sigaction型別的資料結構向訊號處理器的資訊儲存區域中傳遞

資訊。這個資料結構由乙個就能夠了,由於它僅僅是暫時傳遞資料的載體。

可是sigpromask和訊號處理器裡面的sigmask是不一樣的,前者是在程序當前流程設定信

號遮蔽,後者是指定在訊號處理器作用時須要遮蔽掉的訊號。比如,在設定某個特定訊號

的訊號處理器時,我們當然不能讓它的訊號處理器工作了,由於還沒有設定完嗎,這是我

們能夠使用sigprocmask來讓當前的流程開始堵塞該訊號,當設定完訊號處理器以後,再

用sigprocmask恢復被堵塞的訊號。而以後再接收到該訊號時,訊號處理器就能夠工作了。

我的想法是,同乙個訊號在不同的程序裡能夠有不同的訊號處理器(一般應該有乙個預設

處理),當系統中發生乙個訊號時,全部能接受到的程序都能夠接收到這個訊號,並用他

們自己的訊號處理器對這個訊號做出各自的響應。

1.3怎樣用訊號來進行程序間的同步

同步的實現主要是通過在接受訊號之前掛起程序,等待相關訊號。所以涉及到非同步訊號安

全函式的概念。

只是訊號怎樣來實現程序間的相互排斥,我理解不是非常多,我想訊號的主要用處還是在軟中斷

處理和程序同步。

2.訊號量

訊號量和訊號是不同的東西,細緻想想就能夠理解:訊號是實現約定的固定的值,而訊號

量是乙個變數記錄著某些特定資訊。

訊號量這種東西我們在*作系統課程中就已經接觸過了,這裡僅僅是再草草說幾句。訊號量

分為有名和無名兩種。程序間通訊用有名訊號量,同一程序內部通訊一般用無名訊號量。

這個我不再多說。

2.1訊號量相關函式

#include

#include

#include

int semget(key_t key, int nsems, int sem***);

建立乙個新的訊號量組或獲取乙個已經存在的訊號量組。

#include

#include

#include

int semop(int semid, struct sembuf *sop, int nsops);

semop函式能夠一次對乙個或多個訊號量進行*作。

int semctl(int sem_id, int semnum, int cmd,/*union semun arg*/…);

該函式能夠用來獲取一些訊號量的使用資訊或者是來對訊號量進行控制。

2.2我對訊號量機制的理解

對訊號量的*作僅僅有兩個:p, v。

為了在邏輯上便於組織訊號量,訊號量機制中有乙個概念是訊號量組。我們能夠把乙個信

號量組中建立相關的訊號量,這樣邏輯上清楚也便於管理。在使用之前你相同須要對他們

進行初始化:生成或開啟訊號量組,向當中生成或刪除你指定的訊號量。

對訊號量的*作僅僅用兩種,他都是通過semop函式中的sops引數來指定的,假設這個引數

是乙個陣列的話,那麼就是對多個訊號量進行*作。sops引數中的sem_op欄位指明了對信

號量進行的是p*作還是v*作。你僅僅要指定即可了,具體的*作不須要你去實現,函式中

都已經提供了。使用訊號量,你得清楚訊號量組id和訊號量在訊號量組中的位置(事實上也

就是另乙個id)。乙個訊號量必須屬於乙個訊號量組,否則不能被系統所使用。切記!

訊號量和訊號量組是不會被系統所自己主動清理的,所以當你的程序退出前,千萬別忘了清理

你生成的那些訊號量們。

訊號量既能夠實現相互排斥,也能夠實現同步,這裡就不說了,*作系統課程中是有介紹的。

3.訊息佇列

訊息佇列是比較高階的一種程序間通訊方法,由於它真的能夠在程序間傳送massege,你

傳送乙個"i seek you"都能夠。

乙個訊息佇列能夠被多個程序所共享(ipc就是在這個基礎上進行的);假設乙個程序的

訊息太多乙個訊息佇列放不下,也能夠用多於乙個的訊息佇列(只是可能管理會比較復

雜)。共享訊息佇列的程序所傳送的訊息中除了massege本身外另乙個標誌,這個標誌

能夠指明該訊息將由哪個程序或者是哪類程序接受。每個共享訊息佇列的程序針對這個

佇列也有自己的標誌,能夠用來宣告自己的身份。

對於系統中的每個訊息佇列,都有乙個資料結構來代表它,這個資料結構是msqid_ds,

這裡略去不講,在中能夠看到它的原型。

3.1訊息佇列相關函式

使用訊息佇列之前,你要麼獲得這個訊息佇列,要麼自己建立乙個,否則是不能使用訊息

佇列的(我認為這都像是多餘的話,請見諒)。當這個訊息佇列不再使用時,也一定要有

乙個程序來刪除訊息佇列,系統是不會自己主動的清理訊息佇列和msgid_ds的。

int msgget(key_t key, int msg***);

獲取乙個存在的訊息佇列的id,或者是依據跟定的許可權建立乙個訊息佇列。可是怎麼樣去

刪除這個訊息佇列,我還不十分清楚。

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

用來從msqid_ds中獲取非常多訊息佇列本身的資訊。

int msgsnd(int msqid, void *msgp, size_t msgsz, int msg***);

用於向佇列傳送訊息。

int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int

msg***);

從佇列中接收訊息。

我這個文件裡面對訊息佇列中的一些臨界情況所述不多,由於這是我的小結,而非介紹。

在gnu c庫技術中能夠看到它的具體介紹。

Linux程序通訊 訊號

1.程序 在介紹訊號的概念之前,先簡單的介紹一下程序的概念 程序可以理解為一段正在執行的程式,它包括以下三個部分內容 1 一段正在執行的程式 2 與該段程式相關聯的全部資料 資料空間,記憶體,緩衝區 3 程式計數器 pc 2.訊號 可以這麼理解訊號,訊號本身不是訊息,它表達的內容才是訊息。linux...

Linux 程序通訊 訊號

linux 程序通訊 訊號 模擬 乙個程序收到訊號與乙個處理器收到乙個中斷請求可以說一樣的,訊號是非同步的,乙個程序不必通過任何操作來等待訊號的到達,事實上,程序也不知道訊號是什麼時候到達。常見訊號 sighup 從終端發出的訊號 sigint 來自鍵盤中斷訊號 sigkill 訊號結束接受訊號程序...

linux程序通訊 訊號

1.訊號的分類,常用的幾種訊號 訊號的分類 可靠性方面 可靠訊號和不可靠訊號 與時間上的關係 實時訊號與非實時訊號 常見的訊號 sighup 從終端上發出的結束訊號 sigint 來自鍵盤的中斷訊號 ctrl c sigkill 該訊號結束接收訊號的程序,殺死程序 sigterm kill 命令發出...