进程间通信:管道(容量与缓冲区)篇

2017-05-17 17:20 阅读 732 次 评论 0 条

进程间通信(IPC)

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不见。所有进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区读走数据,内核提供的这种机制就是进程间通信(IPC),管道是最基本的IPC机制。

管道容量

管道容量的大小由:pipe buf缓冲条目的数目来共同决定其pipe capacity容量

pipe buf定义的是内核管道缓冲区的容量,这个值由内核设定。我们可以通过ulimit -a命令来查看:

ulimit -a查看到的pipe size一次原子写入为:512 bytes * 8 = 4096 bytes 。

当然另外一个与之对应的就是缓冲条目的个数:它存在于/usr/src/kernels/内核版本/include/linux/pipe_fs_i.h中。当然缓冲条目的个数与linux的内核版本是有关联的,在我的2.6.32-573.el6.x86_64内核上,其缓冲条目个数为:16。

因此就可以得到管道的容量为:16 * 4096 bytes = 65536 bytes。

真正的管道容量即(pipe capacity)。如果你对上述不大理解,我们也可以使用代码来计算管道容量。

当管道满时:

O_NONBLOCK discable: write调用阻塞,直到有程序读走数据。

O_NONBLOCK enable:调用返回-1,errno值为EAGAIN。

管道是一块内存缓冲区,可写下面程序测试管道的容量pipe capacity:

结果也是不言而喻的,当我们一直对管道进行写操作,最后停止的时候即是管道的容量。65536也因此印证了我之前的第一种方法的正确性。

管道缓冲区

在linux中,管道的实现并没有专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个file结构指向同一个临时的VFS索引节点,而这个索引节点又指向一个物理页面而实现。如下图所示:

两个file数据结构定义文件操作例程地址是不同的,其中一个是向管道写入数据的例程地址,而另一个是从管道读处数据的例程地址。这样,用户程序的系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊操作。一个普通的管道仅可供具有共同祖先的两个进程之间共享,并且这个祖先已经建立了供他们使用的管道。

注意,在管道中的数据始终以和写数据相同的次序来进行读,这表示lseek()系统调用对管道不起作用。

版权声明:本文著作权归原作者所有,欢迎分享本文,谢谢支持!
转载请注明:进程间通信:管道(容量与缓冲区)篇 | 术与道的分享
分类:操作系统 标签:,
1024do.com导航_术与道导航平台

发表评论


表情