Linux管道通訊

2021-06-05 14:10:03 字數 2828 閱讀 5642

現在在linux 中使用較多的程序間通訊方式主要有以下幾種。

(1)管道 (pipe )及有名管道 (named pipe ):管道可用於具有親緣關係程序間的通訊,有名管道,除具有管道所具有的功能外,它還允許無親緣關係程序間的通訊。

(2)訊號(signal):訊號是在軟體層次上對中斷機制的一種模擬,它是比較複雜的通訊方式,用於通知接受程序有某事件發生,乙個程序收到乙個訊號與處理器收到乙個中斷請求 效果上可以說是一樣的。

(3)訊息佇列:訊息佇列是訊息的鏈結表,包括posix 訊息佇列systemv 訊息佇列。它克服了前兩種通訊方式中資訊量有限的缺點,具有寫許可權的程序可以向訊息佇列中按照一定的規則新增新訊息;對訊息佇列有讀許可權的程序則可以從訊息佇列中讀取訊息。

(4)共享記憶體:可以說這是最有用的程序間通訊方式。它使得多個程序可以訪問同一塊記憶體空間,不同程序可以及時看到對方程序中對共享記憶體中資料的更新。這種通訊方式需要依靠某種同步機制,如互斥鎖和訊號量等。

(5)訊號量:主要作為程序間以及同一程序不同執行緒之間的同步手段。

(6)套接字(socket):這是一種更為一般的程序間通訊機制,它可用於不同機器之間的程序間通訊,應用非常廣泛。 

管道是linux 中程序間通訊的一種方式。這裡所說的管道主要指無名管道,它具有如下特點:

它只能用於具有親緣關係的程序之間的通訊(也就是父子程序或者兄弟程序之間)。

它是乙個半雙工的通訊模式,具有固定的讀端和寫端。

管道也可以看成是一種特殊的檔案,對於它的讀寫也可以使用普通的read、write等函式。但是它不是普通的檔案,並不屬於其他任何檔案系統,並且只存在於記憶體中。

把子程序的寫端fd[1] 和父程序的讀端fd[0]關閉。這時,父子程序之間建立起了一條「子程序讀父程序寫」的通道。

#include

#include

#include

#include

#include

int main()

if((pid=fork())==0)

close(pipe_fd[0]);

exit(0);

}else if(pid>0)

}管道讀寫注意點

只有在管道的讀端存在時向管道中寫入資料才有意義。否則,向管道中寫入資料的程序將收到核心傳來的sifpipe 訊號 (通常broken pipe 錯誤)。

向管道中寫入資料時,linux 將不保證寫入的原子性,管道緩衝區一有空閒區域,寫程序會試圖向管道寫入資料。如果讀程序不讀取管道緩衝區中的資料,那麼寫操作將會一直阻塞。

父子程序在執行時,它們的先後次序並不能保證,因此,在這裡為了保證父程序已經關閉了讀描述符,可在子程序中呼叫sleep 函式。 

有名管道說明

前面介紹的管道是無名管道,它只能用於具有親緣關係的程序之間,這就大大地限制了管道的使用。有名管道的出現突破了這種限制,它可以使互不相關的兩個程序實現彼此通訊。該管道可以通過路徑名來指出,並且在檔案系統中是可見的。在建立了管道之後,兩個程序可以把它當作普通檔案一樣進行讀寫操作,使用非常方便。不過值得注意的是,fifo 是嚴格地遵循先進先出規則的,對管道及fifo 的讀總是從開始處返回資料,對它們的寫則把資料新增到末尾,它們不支援如lseek()等檔案定位操作。

有名管道的建立可以使用函式mkfifo(),該函式類似檔案中的open()操作,可以指定管道的路徑和開啟的模式。

使用者還可以在命令列使用「 mknod 管道名 p」來建立有名管道。

在建立管道成功之後, 可以使用open、read、write 這些函式了。與普通檔案的開發設定一樣,對於為讀而開啟的管道可在open中設定o_rdonly,對於為寫而開啟的管道可在open中設定o_wronly,在這裡與普通檔案不同的是阻塞問題。由於普通檔案的讀寫時不會出現阻塞問題,而在管道的讀寫中卻有阻塞的可能,這裡的阻塞標誌可以在open 函式中設定為o_nonblock。下面分別對阻塞開啟和 阻塞開啟的讀寫進行一定的討論。

對於讀程序

若該管道是阻塞開啟,且當前fifo內沒有資料,則對讀程序而言將一直阻塞直到有資料寫入。

若該管道是 阻塞開啟,則不論fifo內是否有資料,讀程序都會立即執行讀操作。

對於寫程序

若該管道是阻塞開啟,則寫程序而言將一直阻塞直到有讀程序讀出資料。

若該管道是 阻塞開啟,則當前fifo內沒有讀操作,寫程序都會立即執行讀操作。

下面的例項包含了兩個程式,乙個用於讀管道,另乙個用於寫管道。其中在寫管道的程式裡建立管道,並且作為main 函式裡的引數由使用者輸入要寫入的內容。讀管道讀出了使用者寫入管道的內容,這兩個函式用的是 阻塞讀寫管道。

寫管道:

#include

#include

#include

#include

#include

#include

#include

#define fifo_server "/tmp/myfifo"

main(int argc,char** argv)

else

printf("write %s to the fifo\n",w_buf);

}讀管道:

#include

#include

#include

#include

#include

#include

#include

#define fifo "/tmp/myfifo"

main(int argc,char** argv)

while(1)

printf("read %s from fifo\n",buf_r);

sleep(1);

} pause();

unlink(fifo);

}

Linux 管道通訊

一 定義 管道是單向的 先進先出的。它將乙個程式的輸入和另乙個程式的輸出連線起來。資料被乙個程序讀出後,將被從管道中刪除。分為無名和有名管道兩種。前者用於父程序和子程序間的通訊,後者用於同一系統的兩個程序間通訊。二 無名管道 int pipe int fd 2 其中,fd 0 用於讀管道,fd 1 ...

linux 管道通訊

無名管道 1 管道是半雙工的,只能支援資料的單向流動 兩程序間需要通訊時需要建立起兩個管道 2 使用無名管道通訊的程序必須擁有公共祖先程序 pipe 1 標頭檔案 include 2 定義函式 int pipe int filedes 2 3 函式說明 pipe 會建立管道,並將檔案描述詞由引數fi...

Linux 管道通訊

一 通訊的意義 1 傳輸資料 程序之間的通訊 2 共享資源 不同程序之間共享同一資源 3 事件通知 乙個程序向另乙個或另一組程序傳送訊息通知 4 程序控制 如debug程序等需要完全控制另乙個程序的執行,即能攔截程序操作並知曉其狀態 二 通訊的方式 1 無名管道 pipe 使用檔案操作函式 read...