pipe 半双工_管道为什么是半双工的呢?

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,数据也就冲突了,同时读也同理。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值