UNIX管道 簡介與示例

2021-09-26 16:26:14 字數 2043 閱讀 4454

管道是unix系統最古老的ipc形式。它有以下兩點侷限性:

通常是父程序通過系統呼叫pipe()建立管道,然後fork()出子程序,這兩個程序就可以通過管道進行通訊了。

管道fd:一條管道有兩個檔案描述符,這兩個檔案描述符是在呼叫pipe(fd)建立管道時獲取獲取的。

寫端程序:只向管道寫資料的程序。在使用管道時,先close(fd[0])、再通過write(fd[1])向管道寫資料。

讀端程序:只從管道讀資料的程序。在使用管道時,先close(fd[1])、在通過read(fd[0])從管道讀取資料。

下列**在linux環境下,貼上到本地後可以直接編譯執行。

#include

//declare int pipe(int pipefd[2]);

#include

//pipe_buf

#include

#include

#include

#define msg_from_parent "hello, world!"

int fd[2]

=;//儲存管道的兩個檔案描述符,fd[0] for read, fd[1] for write

intmain

(int argc,

char

**ar**)

pid =

fork()

;if(pid <0)

// fork error

else

if(pid >0)

// branch of parent

/* !!非常重要,writer寫完後必須關閉write end

* 否則reader在讀完管道中的資料後,再次讀管道時會因為沒有資料而一直阻塞 */

close

(fd[1]

);//建議注釋掉這行**,執行檢視下效果。有驚喜喲。你會發現printf()中\n有將緩衝區重新整理的效果

/* 父程序阻塞等待子程序退出 */if(

waitpid

(pid,

null,0

)<0)

printf

("parent exit\n");

}else

// branch of son

;// 故意把buf設的小一點,這樣可以多次讀取管道,觀察更多細節

int readlen =0;

doperror

("after read");

printf

("%s"

, read_buf)

;// printf()的fmt如果加上'\n',其效果可不只是換行喲。

//'\n'其實還有fflush(stdout)的作用:將printf緩衝區的資料重新整理到stdout(即螢幕)上。

}while

(readlen >0)

;close

(fd[0]

);printf

("\nson exit\n");

}return0;

}

如果pipe的一端被關閉,以下兩條規則將生效:

如果寫端關閉,那麼讀端將管道中的資料全部讀完後,如果再次呼叫read,將會返回0。

換言之,如果寫端程序寫完資料後沒有關閉pipe的寫端檔案描述符,那麼讀端程序在讀取乙個不再有資料可讀的管道時會阻塞。

如果讀端關閉,那麼寫端write時,將會產生訊號sigpipe,如果該訊號未被處理,write將返回-1,且errno被置為epipe。

關於linux訊號處理,有時間單寫一篇部落格總結一下。這裡只需要注意,向乙個讀端關閉的管道寫資料,write會返回-1;如果讀端沒有關閉,但是管道的資料一直沒有被讀端程序讀走,那麼當管道中快取資料達到pipe_buf規定的上限時(本示例中列印出的上限是4096 bytes),write會阻塞!

以上兩條規則告訴我們,不管是讀端程序還是寫端程序,用完了管道都要記得關閉啊!否則對端程序再次讀寫管道時會阻塞的!好嚴重的!

**********===

先寫到這裡,其實還有一些需要總結,有時間再填坑吧。

Unix管道與命名FIFO

事實上,管道與fifo是不同的 管道是pipe,基本上pipe 完就可以用了 fifo需要先mkfifo,然後再open 如果mkfifo發現fifo已存在,那麼說明已建立過,此時open pipe沒有名字,只能在親緣程序裡使用。當然,技術上講,可以傳遞描述符後,非親緣也可以用。但比較麻煩 fifo...

UNIX命名管道FIFO

fifo,又稱命名管道,是linux下 unix環境下 一種程序間通訊的機制,應用廣泛。函式mkfifo用於建立命名管道,使用命令man 3 mkfifo可檢視此函式資訊。fifo建立後,可以像普通檔案一樣對其訪問。執行命令 mkfifo tmp fifo cat tmp fifo 程式阻塞。再開啟...

unix下管道程式設計

模型pipe close dup2 read write 使用fopen和fclose的繞行自行查閱相關資料 首先基本了解這四個函式的分別作用 include intpipe int filedes 2 返回值 成功,返回0,否則返回 1。引數陣列包含pipe使用的兩個檔案的描述符。fd 0 讀管道...