| 導購 | 订阅 | 在线投稿
分享
 
 
 

Linux IPC小結

來源:互聯網網民  2006-04-20 05:59:21  評論

作者:coly(李勇)

來源:http://www.linuxforum.net/doc/ipc-coly.html

摘要:介紹了Linux中常用的幾種IPC:信號、信號量、消息隊列、共享內存

現在最常用的進程間通信的方式有:信號,信號量,消息隊列,共享內存。

所謂進程通信,就是不同進程之間進行一些"接觸",這種接觸有簡單,也有複雜。機制不

同,複雜度也不一樣。通信是一個廣義上的意義,不僅僅指傳遞一些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庫技術中可以看到它的詳細介紹。

 
特别声明:以上内容(如有图片或视频亦包括在内)为网络用户发布,本站仅提供信息存储服务。
 
作者:coly(李勇) 來源:[url=http://www.linuxforum.net/doc/ipc-coly.html]http://www.linuxforum.net/doc/ipc-coly.html[/url] 摘要:介紹了Linux中常用的幾種IPC:信號、信號量、消息隊列、共享內存 現在最常用的進程間通信的方式有:信號,信號量,消息隊列,共享內存。 所謂進程通信,就是不同進程之間進行一些"接觸",這種接觸有簡單,也有複雜。機制不 同,複雜度也不一樣。通信是一個廣義上的意義,不僅僅指傳遞一些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庫技術中可以看到它的詳細介紹。
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有