pipe 半雙工 管道為什麼是半雙工的呢?

2021-10-16 16:30:21 字數 2601 閱讀 3112

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個程序間通訊。必須有一對讀寫程序 有名管道使用 建立管道檔案 命...