Linux系統程式設計 程序間通訊(一)

2021-09-12 01:21:43 字數 2976 閱讀 3335

linux系統主要的程序間通訊機制如下:

無名管道(pipe)及命名管道(named pipe):無名管道可用於具有父子關係程序間的通訊;命名管道用於無父子關係的程序之間的通訊。無父子關係的程序可將資訊傳送到某個命名管道中,通過管道名讀取資訊

訊號(signal):程序間的高階通訊方式,用於通知其他程序有何種事件發生。此外,程序可以向自身傳送訊號,還可獲得linux核心發出的訊號。

報文(message)佇列:又稱為訊息佇列,是以posix和system v為標準的通訊機制。報文佇列克服了訊號的資料結構過於簡單的問題,同時也解決了管道資料流無格式和緩衝區長度受限等問題。報文佇列規定了每個程序的許可權,避免了仿冒資訊的出現。

共享記憶體:讓多個程序訪問同乙個記憶體空間,適合於數量極大和資料結構極為複雜的程序間通訊。犧牲了系統的安全性,通常與其他程序間通訊形式混合使用,並避免以根使用者許可權執行。

套接字(socket):一種資料訪問機制,不僅可以用於程序間通訊,還可用於網路通訊。

d—bus:一種高階的程序間通訊機制,以套接字機制為基礎實現

管道本身是一種資料結構,遵循先進先出的原則。先進入管道的資料,也能先從管道中讀出。資料一旦讀取後,就會在管道中自動刪除。

管道通訊以管道資料結構作為內部資料儲存方式,以檔案系統作為資料儲存**。

pipe()函式別定義在標頭檔案unistd.h中,它的一般形式是:

int

pipe

(int filedes[2]

);

pipe系統呼叫需要開啟兩個檔案,檔案識別符號通過引數傳遞給pipe()函式。檔案描述符filedes[0]用來讀取資料,filedes[1]用來寫資料。呼叫成功時,返回值為0,錯誤時返回-1。

管道的工作方式可以總結為以下3個步驟

使用的是write()函式,與寫入普通檔案的操作方法一樣。不同的是管道長度受到限制,管道滿時寫入操作會被阻塞。執行寫操作的程序進入睡眠狀態,直到管道中的資料被讀取。fcntl()函數可將管道設定為非阻塞模式,管道滿時,write()函式的返回值為0。如果寫入資料長度小於管道資料,則要求一次寫入完成,若大於管道長度,寫完管道長度的資料時,write()將被阻塞。

讀取資料使用read()函式實現,讀取的順序與寫入順序相同。當資料被讀取後,這些資料將自動被管道清除。因此,使用管道通訊的方式只能是一對一,不能由乙個程序同時向多個程序傳遞同一資料。

**如果讀取的管道為空,並且管道寫入埠是開啟的,read()函式將被阻塞。**讀取操作的程序進入睡眠狀態,直到有資料寫入管道為止。fcntl()函式也可將管道讀取模式設定為非阻塞。

管道雖然有兩個埠,但只有乙個埠能被開啟,避免了同時對管道進行讀和寫的操作。關閉埠使用的是close()函式,關閉讀埠時,在管道上進行寫操作的程序將收到sigpipe訊號,關閉寫埠時,進行讀操作的read()函式將返回0。如下例所示:

#include

#include

#include

#include

#include

#include

intmain()

if((cld_pid=

fork()

)==0)

else

wait

(&status)

;return0;

}

輸出結果如下:

上述程式中首先建立了乙個管道,並且將管道的檔案識別符號傳遞給fp陣列。該陣列有兩個元素,fd[0]是讀取管道的埠,fd[1]是寫入管道的埠。然後,通過fork()系統呼叫建立子程序。父程序的操作是向管道寫入資料,子程序的操作是讀取管道內的資料,最後子程序將所讀資料顯示到終端上。

sprintf()函式是向緩衝區中寫入內容。

系統呼叫dup用來複製乙個檔案描述符,該操作是通過對u區中檔案描述符複製實現的。因此,系統呼叫dup能讓多個檔案描述符指向同一檔案,便於管道操作。與該呼叫相關的函式有兩個,分別是dup()函式和dup2()函式,一般形式如下:

int

dup(

int oldfd)

;int

dup2

(int oldfd,

int newfd)

;

兩個函式的區別為,dup()函式自動分配新檔案描述符,並保證該檔案描述符沒有被使用。dup2()函式使用newfd引數指定新檔案描述符,如果該檔案描述符已存在,則覆蓋對應的檔案描述符。

新舊檔案描述符可交換使用,並共享檔案鎖、檔案指標和檔案狀態。

呼叫成功時,函式返回值為新檔案描述符,否則返回-1。例如下例:

#include

#include

#include

#include

#include

intmain()

close(1

);//標準輸出的檔案描述符為1

dup(fd)

;close

(fd)

;puts

("該行資料將輸出到檔案中");

return0;

}

程式執行結果如下:

上述**中,標準輸出(檔案描述符為1)關閉,並將乙個普通檔案output的檔案描述符複製到標準輸出上。因為剛關閉了檔案描述符,檔案描述符表的第乙個空表項是1,dup()函式將呼叫fd的檔案描述符複製到該位置上。所以,程式以後的向標準輸出寫的內容都寫到了檔案output中。

linux系統程式設計 程序間通訊 pipe

程序間通訊 pipe 每個程序各自有不同的使用者位址空間,任何乙個程序的全域性變數在另乙個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,程序1把資料從使用者空間拷到核心緩衝區,程序2再從核心緩衝區把資料讀走,核心提供的這種機制稱為程序間通訊 ipc,interproce...

Linux系統程式設計 程序間通訊 IPC

利用檔案進行程序間通訊的程式示例 include include include include include include intmain if pid 0 write fd1,str,strlen str printf child wrote over n if pid 0 sleep 1 ...

系統程式設計 程序間通訊 概述

程序間通訊概述 1.什麼是程序間通訊?什麼是執行緒間通訊?程序間通訊 在使用者空間實現程序間通訊是不可能的,程序間通訊通過linux核心物件來實現。執行緒間通訊 這在使用者空間就可以實現,甚至可以通過全域性變數來通訊。2.有哪幾種程序間通訊方式?管道通訊 無名管道 有名管道 檔案系統中有名 訊號通訊...