linux的管道實現是個環形緩衝區:
* struct pipe_buffer - a linux kernel pipe buffer
* @page: the page containing the data for the pipe buffer
* @offset: offset of data inside the @page
* @len: length of data inside the @page
* @ops: operations associated with this buffer. see @pipe_buf_operations.
* @flags: pipe buffer flags. see above.
* @private: private data owned by the ops.
struct pipe_buffer {
struct page *page;
unsigned int offset, len;
const struct pipe_buf_operations *ops;
unsigned int flags;
unsigned long private;
* struct pipe_inode_info - a linux kernel pipe
* @mutex: mutex protecting the whole thing
* @wait: reader/writer wait point in case of empty/full pipe
* @nrbufs: the number of non-empty pipe buffers in this pipe
* @buffers: total number of buffers (should be a power of 2)
* @curbuf: the current pipe buffer entry
* @tmp_page: cached released page
* @readers: number of current readers of this pipe
* @writers: number of current writers of this pipe
* @files: number of struct file referring this pipe (protected by ->i_lock)
* @waiting_writers: number of writers blocked waiting for room
* @r_counter: reader counter
* @w_counter: writer counter
* @fasync_readers: reader side fasync
* @fasync_writers: writer side fasync
* @bufs: the circular array of pipe buffers
* @user: the user who created this pipe
struct pipe_inode_info {
struct mutex mutex;
wait_queue_head_t wait;
unsigned int nrbufs, curbuf, buffers;
unsigned int readers;
unsigned int writers;
unsigned int files;
unsigned int waiting_writers;
unsigned int r_counter;
unsigned int w_counter;
struct page *tmp_page;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
struct pipe_buffer *bufs;
struct user_struct *user;
curbuf是當前快取區的下標,每個緩衝區裡有offset和len記錄資料寫到的位置,讀寫的時候是要修改這些資訊的。
如果兩個程序同時進行讀或者同時進行寫,必要會導致資料衝突,所以核心會對管道上鎖(pipe_inode_info裡的mutex),所以是半雙工的。
比較簡單的實現可以看xv6的實現:
struct pipe {
struct spinlock lock;
char data[pipesize];
uint nread; // number of bytes read
uint nwrite; // number of bytes written
int readopen; // read fd is still open
int writeopen; // write fd is still open
直接一塊連續的記憶體data,用兩個數字nread、nwrite記錄讀寫數,通過pipesize取模得到在data上的讀寫位置,用自旋鎖保護。如果沒有鎖,兩個程序就能同時寫資料到data和修改nwrite,資料也就衝突了,同時讀也同理。
pipe 半雙工 linux pipe使用小結
pipe作為linux中最基礎的程序間通訊機制,經常在shell中使用,例如ps aux grep aaa 即建立了乙個管道,而linux 下c程式同樣可以通過系統呼叫pipe在父子程序間使用管道功能。pipe函式原型如下 include int pipe int pipefd 2 通過函式引數返回...
單工 半雙工 全雙工的區別
半工 只支援乙個方向的資料傳輸 在同一時間只有一方能接受或傳送訊息,不能實現雙向通訊。電視 廣播 半雙工 資料傳輸允許資料在兩個方向上傳輸,但是同一時刻僅允許資料在同乙個方向上傳輸,實際上是一種切換方向的單工通訊 在同一時間只可以有一方接受或傳送訊息,可以實現雙向通訊。全雙工 資料傳輸允許雙向同時傳...
程序間通訊 管道(半雙工通訊)
乙個程序輸出資料到另乙個程序資料輸入的通道。半雙工通訊 同一時間,只能一端讀另一端寫,因為只有一條通道 在磁碟上會存在乙個管道檔案標識,但管道檔案不占用磁碟block空間,資料會快取在記憶體上。可應用於同一臺主機上的有許可權訪問的任意n個程序間通訊。必須有一對讀寫程序 有名管道使用 建立管道檔案 命...