linux 進程間的通信

現在linux使用的進程間通信方式:
(1)管道(pipe)和有名管道(FIFO)
(2)信號(signal)
(3)消息隊列
(4)共享內存
(5)信號量
(6)套接字(socket)

爲何進行進程間的通信:
A、數據傳輸:一個進程需要將它的數據發送給另一個進程,發送的數據量在一個字節到幾M字節之間
B、共享數據:多個進程想要操作共享數據,一個進程對共享數據的修改,別的進程應該立刻看到。
C、通知事件:一個進程需要向另一個或一組進程發送消息,通知它(它們)發生了某種事件(如進程終止時要通知父進程)。
D、資源共享:多個進程之間共享同樣的資源。爲了作到這一點,需要內核提供鎖和同步機制。
E、進程控制:有些進程希望完全控制另一個進程的執行(如Debug進程),此時控制進程希望能夠攔截另一個進程的所有陷入和異常,並能夠及時知道它的狀態改變。

一、信號量

常見的信號類型

參考:http://blog.csdn.net/ljianhui/article/details/10128731

對信號量的理解:

信號量是一個非負整數(車位數),所有通過它的線程/進程(車輛)都會將該整數減一(通過它當然是爲了使用資源),當該整數值爲零時,所有試圖通過它的線程都將處於等待狀態。在信號量上我們定義兩種操作: Wait(等待) 和 Release(釋放)。當一個線程調用Wait操作時,它要麼得到資源然後將信號量減一(P操作),要麼一直等下去(指放入阻塞隊列),直到信號量大於等於一時。Release(釋放)實際上是在信號量上執行加操作(V操作),對應於車輛離開停車場,該操作之所以叫做“釋放”是因爲釋放了由信號量守護的資源


對信號量有4種操作(include<semaphore>):

  1. 初始化(initialize),也叫做建立(create)

    int sem_init(sem_t *sem, int pshared, unsigned int value);

  2. 等信號(wait),也可叫做掛起(suspend)

      int sem_wait(sem_t *sem);

  3. 給信號(signal)或發信號(post)

      int sem_post(sem_t *sem);

  4.清理(destroy)

       int sem_destory(sem_t *sem);

編程步驟:

  創建信號量或獲得在系統已存在的信號量

    調用semget()函數

    不同進程使用同一個信號量鍵值來獲得同一個信號量

  初始化信號量

    使用semctl()函數的SETVAL操作

    當使用二維信號量時,通常將信號量初始化爲1

  進行信號量的PV操作

    調用semop()函數

    實現進程之間的同步和互斥的核心部分

  如果不需要信號量,則從系統中刪除它

    使用semctl()函數的IPC_RMID操作

    在程序中不應該出現對已被刪除的信號量的操作

常用函數的說明




二、共享內存

共享內存的接口函數:

# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/shm.h>

key_t  ftok(const char *pathname, int proj_id);

函數用於生成一個鍵值:key_t key,該鍵值將作爲共享內存對象的唯一性標識符,並提供給爲shmget函數作爲其輸入參數;ftok 函數的輸入參數包括一個文件(或目錄)路徑名:pathname,以及一個額外的數字:proj_id,其中pathname所指定的文件(或目錄)要求必須已經存在,且proj_id不可爲0in shmget(key_t key, int size, int shmflg);

函數用於創建(或者獲取)一個由key鍵值指定的共享內存對象,返回該對象的系統標識符:shmid

第一個參數,與信號量的semget函數一樣,程序需要提供一個參數key(非0整數),它有效地爲共享內存段命名,shmget函數成功時返回一個與key相關的共享內存標識符(非負整數),用於後續的共享內存函數。調用失敗返回-1.

不相關的進程可 以通過該函數的返回值訪問同一共享內存,它代表程序可能要使用的某個資源,程序對所有共享內存的訪問都是間接的,程序先通過調用shmget函數並提供一 個鍵,再由系統生成一個相應的共享內存標識符(shmget函數的返回值),只有shmget函數才直接使用信號量鍵,所有其他的信號量函數使用由 semget函數返回的信號量標識符。

第二個參數,size以字節爲單位指定需要共享的內存容量

第三個參數,shmflg 是權限標誌,它的作用與open函數的mode參數一樣,如果要想在key標識的共享內存不存在時,創建它的話,可以與IPC_CREAT做或操作。共享 內存的權限標誌與文件的讀寫權限一樣,舉例來說,0644,它表示允許一個進程創建的共享內存被內存創建者所擁有的進程向共享內存讀取和寫入數據,同時其 他用戶創建的進程只能讀取共享內存。


void*  shmat(int shmid, const void *shmaddr, int shmflg);

函數用於建立調用進程與由標識符shmid指定的共享內存對象之間的連接;

第一個參數,shm_id是由shmget函數返回的共享內存標識。

第二個參數,shm_addr指定共享內存連接到當前進程中的地址位置,通常爲空,表示讓系統來選擇共享內存的地址。

第三個參數,shm_flg是一組標誌位,通常爲0。

調用成功時返回一個指向共享內存第一個字節的指針,如果調用失敗返回-1


int   shmdt(void *shmaddr);

函數用於斷開調用進程與共享內存對象之間的連接;數用於斷開調用進程與共享內存對象之間的連接;

int   shmctl(int shmid, int cmd, struct shmid_ds *buf);

函數用於對已創建的共享內存對象進行查詢、設值、刪除等操作;

第一個參數,shm_id是shmget函數返回的共享內存標識符。

第二個參數,command是要採取的操作,它可以取下面的三個值 :

    IPC_STAT:把shmid_ds結構中的數據設置爲共享內存的當前關聯值,即用共享內存的當前關聯值覆蓋shmid_ds的值。

    IPC_SET:如果進程有足夠的權限,就把共享內存的當前關聯值設置爲shmid_ds結構中給出的值

    IPC_RMID:刪除共享內存段

第三個參數,buf是一個結構指針,它指向共享內存模式和訪問權限的結構。

struct shmid_ds  

{  

    uid_t shm_perm.uid;  

    uid_t shm_perm.gid;  

    mode_t shm_perm.mode;  

}; 




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章