Linux IPC小結(轉)

BSDLite發表於2007-08-11
Linux IPC小結(轉)[@more@]現在最常用的程式間通訊的方式有:訊號,訊號量,訊息佇列,共享記憶體。
所謂程式通訊,就是不同程式之間進行一些"接觸",這種接觸有簡單,也有複雜。機制不
同,複雜度也不一樣。通訊是一個廣義上的意義,不僅僅指傳遞一些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 semflg);
建立一個新的訊號量組或獲取一個已經存在的訊號量組。

#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 msgflg);
獲取一個存在的訊息佇列的ID,或者是根據跟定的許可權建立一個訊息佇列。但是怎麼樣去
刪除這個訊息佇列,我還不十分清楚。
Int msgctl(int msqid, int cmd, struct msqid_ds *buf);
用來從msqid_ds中獲取很多訊息佇列本身的資訊。
Int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg);
用於向佇列傳送訊息。
Int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int
msgflg);
從佇列中接收訊息。
我這個文件裡面對訊息佇列中的一些臨界情況所述不多,因為這是我的小結,而非介紹。
在GNU C庫技術中可以看到它的詳細介紹。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-947663/,如需轉載,請註明出處,否則將追究法律責任。

相關文章