歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

關於進程間通信的學習心得

進程:進程是指獨立地址空間的指令序列

進程的五種狀態:新建,就緒,運行,睡眠,僵死

進程間通信:是不同進程之間進行一些"接觸",這種接觸有簡單,有復雜。機制不同,復雜度也不同。通信是一個廣義上的意義,不僅指大批量數據傳送,還包括控制信息的傳送,但使用方法是基本相同的。

基本的進程通信機制

1.傳統UNIX-IPC機制:信號和管道

2.SystemV的IPC機制:共享內存、信號量和消息隊列

3.起源於Unix BSD版本的套結字(Socket)

4.遠程過程調用(RPC)

信號:Unix系統中使用的最古老的進程間通訊的方法之一,用於向一個或多個進程發送異步事件的信號。信號可以類比於DOS下的INT或者是Windows下的事件。在有一個信號發生的時候,相應的信號就會發送給相應的進程。

信號機制的實現

1.信號包括待處理信號和被阻塞信號

2.如果產生了一個被阻塞的信號,它一直保留待處理,直到被解除阻塞。

3.系統保存每一個進程如何處理每一種可能的信號的信息。

4.系統判斷進程是希望忽略這個信號還是讓內核處理。進程通過執行系統調用改變缺省的信號處理。

對信號的處理

1.初始化信號集,只有在信號集裡面的信號才會被考慮

2.安裝信號處理器。所謂信號處理器,就是指定了一些對信號的處理方法。在安裝的時候,一定要對特定的信號賦予正確的信號處理函數。

信號相關函數

int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);為進程安裝信號處理器,struct sigaction數據結構是用來保存信號處理器的相關信息。

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);判斷某個信號是否在信號集中。

int sigprocmask(int how,const sigset_t *set, sigset_t *oset);設置進程的信號屏蔽碼。信號屏蔽碼可以用來在某段時間內阻塞一些信號集中的信號。

管道通信:是最古老的Unix IPC工具,一個進程從管道一頭寫數據,另一個進程從管道另一頭讀數據,以實現它們之間通信的共享方式,又稱pipe文件。由於發送和接收都是利用管道進行通信的,故稱為管道通信。通信方式是單向的。管道類型分為:無名管道、命名管道

管道通信的思想

1.發送進程可以源源不斷的從pipe一端寫入數據流,在規定的pipe文件的最大長度(如4096字節)范圍內,每次寫入的信息長度是可變的。

2.接收進程在需要時可以從pipe的另一端讀出數據,讀出單位長度也是可變的。

基本管道調用函數

int do_pipe(int *fd);創建管道

static int pipe_release(struct inode *inode, int decr, int decw);管道釋放

無名管道II

顯示了每一個file數據結構包含了不同的文件操作例程的向量表的指針:一個用於寫,另一個從管道中讀。這掩蓋了和通用的讀寫普通文件的系統調用的不同。當寫進程向管道中寫的時候,字節拷貝到了共享的數據頁,當從管道中讀的時候,字節從共享頁中拷貝出來。

命名管道:又名FIFO,它不是臨時的對象,而是文件系統中的實體,可以用mkfifo命令創建。系統必須處理在寫進程打開FIFO之前打開FIFO讀的進程,以及在寫進程寫數據之前讀的進程。它使用和無名管道一樣的數據結構和操作。

       (寫入端)[Fd1]→pipe(fd)→[Fd0](讀出端)

信號量:信號量(Semaphore)和信號是不同的東西,信號是實現約定的固定的值,而信號量是一個變量記錄著某些特定信息,它的使用主要是用來保護共享資源,使得該資源在一個時刻只讓一個進程擁有。

信號量的數據結構:使用semid_ds數據結構表達信號量。系統中所有的semid_ds數據結構都由semary指針向量表指向。每一個信號燈數組中都有sem_nsems,通過sem_base指向的一個sem數據結構來描述

信號量機制的實現

1.對信號量的操作只有兩個:P、V。

2.為了在邏輯上便於組織信號量,信號量機制中有一個概念是信號量組。我們在一個信號量組中創建相關的信號量,這樣邏輯上清晰也便於管理。

3.在使用之前同樣需要對他們進行初始化:生成或打開信號量組,向其中生成或刪除指定的信號量。

4.一個信號量必須屬於一個信號量組,否則不能被系統所使用。

5.信號量和信號量組是不會被系統所自動清理的,所以在進程退出前,需要及時清理生成的那些信號量。

信號量的相關函數

int semget(key_t key, int nsems, int semflg);創建一個新的信號量組或獲取一個已經存在的信號量組。

int semop(int semid, struct sembuf *sop, int nsops);一次對一個或多個信號量進行操作,用於P、V操作。

Int semctl(int sem_id, int semnum, int cmd, union semun arg);用來獲取一些信號量的使用信息或者是來對信號量進行控制。

共享內存

    共享內存是進程通信的一個重要方法,為進程提供了直接通信的手段。操作系統中一個或多個進程通過同時出現在它們的虛擬地址空間的內存通訊,該虛擬內存被每個共享進程的頁表所引用,它們的地址無需相同。進程對共享內存的訪問是受控的,信號量等機制實現了共享內存訪問的同步

共享內存的簡單原理

每一個新創建的內存區域都用一個shmid_ds數據結構來表達。這些數據結構保存在shm_segs向量表中。Shmid_ds數據結構描述了這個共享內存取有多大、多少個進程在使用它以及共享內存如何映射到它們的地址空間。由共享內存的創建者來控制對於這塊內存的訪問權限和它的key是公開或私有。如果有足夠的權限它也可以把共享內存鎖定在物理內存中。每一個希望共享這塊內存的進程必須通過系統調用粘附(attach)到虛擬內存。這為該進程創建了一個新的描述這塊共享內存的vm_area_struct數據結構。進程可以選擇共享內存在它的虛擬地址空間的位置或者由Linux選擇一塊足夠的的空閒區域。這個新的vm_area_struct結構放在由shmid_ds指向的vm_area_struct列表中。通過vm_next_shared和vm_prev_shared把它們連在一起。

Copyright © Linux教程網 All Rights Reserved