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 半双工_管道为什么是半双工的呢?相关推荐

  1. python 归纳 (二二)_多进程数据共享和同步_管道Pipe

    # -*- coding: utf-8 -*- """ 多进程数据共享 管道Pipe逻辑:2个进程,各自发送数据到管道,对方从管道中取到数据总结:1.只适合两个进程2.r ...

  2. 进程间的通信方式(二):管道Pipe和命令管道FIFO

    1.概述 管道是最初的Unix IPC通信,可追溯到1973年的Unix第三版.尽管对于许多操作来说很有用,但它们的根本局限于没有名字,只能由亲缘关系的进程使用.这一点随着FIFO的加入System  ...

  3. Linux中的pipe(管道)与named pipe(FIFO 命名管道)

    catalogue 1. pipe匿名管道 2. named pipe(FIFO)有名管道 1. pipe匿名管道 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入 ...

  4. 匿名管道(Pipe)和命名管道(FIFO)

    catalogue 1. pipe匿名管道 2. named pipe(FIFO)有名管道 1. pipe匿名管道 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入 ...

  5. linux学习---linux基于文件的IPC(匿名管道pipe,命名管道mkfifo,普通文件,socket文件)

    常用的IPC分为两个类别,一是基于文件,而是基于内存 基于文件的分别有匿名管道,有名管道,普通的文件共享,socket文件 基于内存的有普通内存共享(本文章没有介绍),共享内存,共享信号量,消息队列 ...

  6. pipe创建匿名管道`

    pipe创建的管道为匿名管道,匿名管道只能在有关系的进程之间使用,例如父进程和子进程,由同一个父进程创建的子进程或称为兄弟进程 如图所示若管道只有一个,并且管道只能进程单向通讯,因此,在子进程继承父进 ...

  7. 【Linux系统编程学习】匿名管道pipe与有名管道fifo

    此为牛客Linux C++和黑马Linux系统编程课程笔记. 0. 关于进程通信 Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间.任何一个进程的全局变量在另一个进程中都看不到 ...

  8. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  9. linux pipe 命名管道,linux 进程学习笔记-named pipe (FIFO)命名管道

    与"无名管道"不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如"/tmp/my_fifo",其对应到磁盘上的一个管道文件,如果我们用f ...

最新文章

  1. C++中try/catch/throw的使用
  2. Centos 6 常用服务部署命令说明
  3. Redis+Mysql模式和内存+硬盘模式的异同
  4. 深入浅出KNN算法(二) sklearn KNN实践
  5. linux系统it固定资产管理系统包_固定资产管理系统单机版有哪些特点?
  6. FreeModbus RTU传输
  7. 网站白痴的 ASP.NET website 学习日志
  8. 如何开启outlook邮箱的pop3和smtp_怎么在电子邮件客户端上登录腾讯邮箱(QQ邮箱 )?
  9. xenomai linux测试,Xenomai 实时线程 select 测试
  10. php fork demo,php多进程demo
  11. 科普知识:深网和暗网
  12. 推销自己的最佳媒介之一就是博客
  13. 处理行标签与行标签中间的空隙
  14. 数据挖掘工具主要有哪几种?
  15. C语言 课程设计 实现简单的车辆管理系统
  16. 901虎年期待和变元的哥德尔数配置——哥德尔原著英译本拆解汉译之五
  17. java中的画图公式_GitHub - oneSaber/Compiler-java: 函数绘图语言java实现
  18. 受损固态硬盘(SSD)数据恢复方法
  19. java socket 打印机_思普瑞特,小票打印机和标签打印机java网络驱动设计与实现...
  20. 【Python应用探索笔记二】百度语音合成与识别

热门文章

  1. telnet服务器端口无响应,分析Telnet 1433端口不通的原因
  2. 阿里蚂蚁金服五面,血与泪的总结(附面试题)
  3. 九月SLAM相关论文速递
  4. 证明三角形中重心坐标公式
  5. clion使用Eigen
  6. 秦汉三国政治史专题:秦人建国道路
  7. 小程序开发—发布流程及注意事项
  8. 引发线程安全的原因是什么?怎么解决?程序员一定要掌握的东西
  9. 向元气满满的日本中小企业学习2
  10. (二十五) 冷启动和热启动