您的位置:首页 > 运维架构 > Linux

linux ---- 进程 --- 3

2013-05-30 21:33 197 查看
4. 进程间通信





每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中看不到,所以进程之间要想交换数据,必须要在内核中进行,在内核中开辟一段缓冲区,进程1把数据写入这个缓冲区,进程2从这个缓冲区读取数据,内核提供的这种机制就是所谓的进程之间的通信,即IPC  (InterProcess Communication)

1> 管道   --- 最基本的IPC通信
 #include <unistd.h>
int pipe(int filedes[2]);

调用pipe函数时,在内核中开辟一块缓冲区(即管道)用于通信,它有一个读端,一个写端,然后通过filedes参数传出给用户程序两个文件描述符, filedes[0] 指向管道读端, filedes[1]指向管道写端。
pipe函数调用成功返回0, 失败返回-1。

管道通信过程:




父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。
父进程调用fork创建子进程, 那么子进程也有两个文件描述符指向这个管道
父进程关闭管道读端, 子进程关闭管道写端
使用管道有一些限制:

两个进程之间只能实现单向通信
管道的读写端通过打开的文件描述符来传递,因此要通信的两个进程必须从它们的公共祖先那里继承管道文件描述符。
注意事项:

如果所有指向管道写端的文件描述符都关闭了,也就是管道的写端的引用计数为0了,而仍然有进程从管道里面读取数据,那么管道中剩余的数据会被读取,完全读取后,再次读取,返回为0.就像读到了文件的末尾一样。

如果有指向管道写端的文件描述符没关闭了,且管道的写端的引用计数大于0,而持有管道写端的进程也没有往管道中写数据,这个时候有进程从管道中读数据时,管道中剩余的数据会被读取,完全读取后,再次读取,会阻塞,直到管道中有数据可读了,才读取数据并返回。

如果所有指向管道读端的文件描述符都关闭了,这时候有进程向管道中写数据,那么该进程会受到一个SIGPIPE的信号,这个信号默认会让程序异常退出。
如果有指向管道读端文件描述符没关闭,而只有读端的进程也没有从管道中读取数据,那么这时候有进程向管道中写数据,那么在管道写满时,再次write会阻塞。

2> 其他IPC机制
进程间通信必须要通过内核提供的通道, 而且必须要一种办法能标识内核提供的通道, 上面的管道是通过打开文件描述符来标识的,如果要互相通信的几个进程没有从公共祖先那里继承文件描述符,他们该怎么通信呢?
   内核提供一个通道这个不成问题,问题是如何表示这个通道,才能使各进程都可以访问它呢?文件系统的文件名是全局的,每个进程都可以访问, 因此可以用文件系统中的文件名来表示一个IPC通道。

FIFO和UNIX Domain Socket 这两种IPC机制都是利用文件系统的特殊文件来标识的。可以用mkfifo命令来创建一个FIFO文件.
----------------------------------------------------------------
$ mkfifo hello
$ ls -l hello
prw-r--r-- 1 akaedu akaedu 0 2008-10-30 10:44 hello
----------------------------------------------------------------
FIFO文件在磁盘上没有数据块, 仅用来表示内核中的一条通道, 各进程都可以打开这个文件进行read/write, 实际上是在读写内核通道(根本原因是这个文件的file结构体的read/write指针和常规文件不同)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 进程