linux下的程序通訊基本上是從unix平台上的程序通訊繼承來的。而對unix發展做出最大貢獻的倆大主力at&t的貝爾實驗室及bsd(加州大學伯克利分校的伯克利軟體發布中心)在程序的通訊方面的側重點有所不同。前者是對unix早期的程序間通訊手段進行了系統的改進和擴充,形成了「system v ipc」,其通訊主要侷限在單個計算機內;後者跳出了該限制,形成了基於套接字(socket)的程序間通訊機制。而linux則把兩者的優勢都繼承下來。
linux 程序間通訊方式:
傳統: /* 通用級 */
有名管道:mkfifo write read close無名管道:pipe write read close
訊號:signal kill raise pause alarm
posix:
/* 新的、輕量級 */
訊號量: man sem_overview
有名:sem_open sem_close sem_unlink
無名:sem_init sem_destroy
sem_post sem_wait sem_getvalue
共享記憶體: man shm_overview
shm_open shm_unlink mmap munmap
訊息佇列: man mq_overview
mq_open mq_close mq_unlink mq_send mq_receive
system v:
/* 古老的、重量級 */
訊號量集:
semget semctl semop
共享記憶體:
shmget shmctl shmat shmop
訊息佇列:
msgget msgop msgctl msgsnd msgrcv
bsd:
socket通訊
連線:
server: socket bind listen accept recv send
client: socket bind connect send recv
無連線:
server: socket bind recvfrom sendto
client: socket bind sendto recvfrom
無名管道
它只能用於有親緣關係(父子,兄弟等)的程序間的通訊。有名管道(命名管道)它是乙個半雙工的通訊模式,具有固定的讀端和寫端。
管道可以看成特殊的檔案,對它的操作可以使用read和write,它不屬於任何檔案系統,存在於記憶體中。
它可以實現不相關的兩個程序間彼此通訊。常用函式命令管道fifo嚴格按照先進先出的規則。不支援lseek操作。
命名管道在檔案系統中是可見的,使用mkfifo可以建立該型別檔案
pipe,read,write,mkfifo
注意事項
int pipe(int fd[2]),下標為0的為讀端,下標為1的為寫端
只有在讀端存在的時候寫入才有意義,否則,向管道寫入資料的程序將收到sigpipe訊號,程序被殺死。
訊號是在軟體層次上對中斷機制的一種模擬,訊號是非同步的,乙個程序不必通過任何操作來等待訊號到來,即程序處於未執行的狀態,核心會儲存其訊號,待程序執行時在傳給它。最常用的傳送訊號的系統函式有kill(),raise(),alarm(),setitimer()和sigqueue()等。
程序可以通過三種方式響應乙個訊號
忽略訊號
忽略訊號即對訊號不做任何處理,其中執行預設操作sigkill和sigstop不能被忽略
。
linux對每種訊號都有預設的處理,使用該方式進行處理訊號。捕捉訊號
使用signal()函式註冊訊號處理函式,在訊號來時執行預定的處理函式。常用函式
傳送訊號的函式:kill(),raise()
捕捉訊號的函式:alarm(),pause()
註冊訊號處理的函式:signal(),sigaction()
訊息佇列就是一些訊息的列表,使用者可以在訊息佇列中新增小寫和讀取訊息等。從這點上看,訊息佇列具有fifo的特性,但是它可實現訊息的隨機查詢,比fifo具有更大的優勢,同時這些訊息存在於核心中,有佇列id來標識。使用ipcs -q檢視當前系統的訊息佇列狀態。常用函式
ftok() 獲取key
msgget() 獲取訊息佇列id
msgsnd() 向訊息佇列傳送訊息
msgrcv() 從訊息佇列接收訊息
msgctl() msg通用控制函式
為了在多個程序間交換資訊,核心專門流出了一塊記憶體區,這塊記憶體可以由需要訪問的程序對映到自己的私有位址空間,從而程序可以直接讀寫這一段記憶體,不需要複製資料。因此共享記憶體是最為高效的程序間通訊方式。使用ipcs -m檢視當前系統中共享記憶體使用狀態。常用函式
ftok() 獲得key
shmget() 獲得共享記憶體id
shmat() 對映共享記憶體
shmdt() 取消對映共享記憶體
shmctl() 共享記憶體控制函式
背景:在多工的作業系統下,程序間可能存在一定的制約關係。例如間接制約和直接制約。
互斥關係
間接制約指程序間相互爭奪共享資源的關係,例如程序爭奪cpu時間片、i/o裝置。同步關係我們把程序間爭奪共享資源的關係稱為互斥關係。
直接制約指程序間相互合作的關係,即需要按條件有固定順序的訪問某資源。例如讀者與寫者問題,程序a的輸出結果,程序b需要用到,所以程序b必須先等程序a完成。對於同步與互斥的關係我們可以理解為:我們把程序間有固定順序的操作某些資源的合作關係稱為同步關係。
同步關係包含互斥關係,互斥關係是一種特殊的同步關係。
同步與互斥的根本原因在於資源不足,共享資源。這些共享的資源被稱為臨界資源,這些操作臨界資源的**稱為臨界區。
訊號量:
訊號量是用來解決程序間同步與互斥問題的一種程序間通訊機制,包括乙個稱為訊號量的變數和在該訊號量下等待的資源的程序等待佇列,以及訊號量進行的兩個原子操作(pv操作),其中訊號量對應某一種資源,取乙個非負整數。訊號量的值指當前可用該資源的數量,若為0表示該資源當前沒有可用資源。
多個訊號量又被稱為訊號燈集。
pv原子操作的具體定義如下
p操作
如果有可用資源(訊號量值》0),則占用乙個資源(給當前訊號量值減一,進入臨界區**);如果當前沒有可用資源(訊號量值=0),則程序被阻塞直到系統將資源分配給該程序(進入等待佇列,直到資源輪到該程序使用)。v操作
如果在該訊號的等待佇列中有程序在等待資源,則喚醒乙個阻塞程序;如果沒有程序等待該資源,則釋放乙個資源(給當前訊號量值加一)。常用函式
ftok() 獲取key
semget() 獲取訊號燈集id
semop() 對訊號燈集操作
semctl() 訊號燈集的控制函式
sem_wait() 對訊號量進行p操作
sem_post() 對訊號量進行v操作
使用ipcs -s檢視當前系統訊號量使用情況。
linux下程序間通訊
linux下程序間通訊的幾種主要手段簡介 管道 pipe 及有名管道 named pipe 管道可用於具有親緣關係程序間的通訊,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關係程序間的通訊 訊號 signal 訊號是比較複雜的通訊方式,用於通知接受程序有某種事件發...
linux下程序間通訊(2)
1.訊息佇列 訊息佇列是由訊息的鍊錶,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少 管道只能承載無格式位元組流以及緩衝區大小受限等缺點。2.訊息佇列結構定義 struct msqid ds msgque msgmni 向量 msgque msgmni 是乙個msqid ds結構...
Linux下程序間通訊 管道通訊
1.程序間通訊 ipc inter process communication 比較好理解概念的就是程序間通訊就是在不同程序之間傳播或交換資訊。2,linux下ipc機制的分類 管道 訊號 共享記憶體 訊息佇列 訊號量 套接字 我今天主要想講的是管道通訊 管道通訊特點 1 管道是最古老的ipc,但目...