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

关于Linux进程通信

2009-12-05 09:56 232 查看
一、多进程

fork () 的作用是什么?换句话说,你用 fork () 的目的是什么?
――是为了产生一个新的进程,地球人都知道 :)
产生一个什么样的进程?
――和你本来调用 fork () 的那个进程基本一样的进程,其实就是你原来进程的副本;
真的完全一样吗?
――当然不能完全一样,你要两个除了 pid 之外其它一模一样的进程干什么,就算memory
再多也不用这么摆谱吧?
哪里不一样?
――当然最重要的是 fork () 之后执行的代码不一样,you know, i know :)
怎么实现呢?
――如果是 Windows,它会让你在 fork () 里面提供一大堆东西,指明这个那个什么的……
我用的是 unix 啊
――所以很简单,unix 会让两个进程(不错,原来是一个,unix 替你复制了一个,现在有两个)
在 fork () 之后产生不同:返回值不同。其中一个进程(使用新的 pid)里面的 fork () 返回零,
这个进程就是“子进程”;而另一个进程(使用原来的 pid)中的 fork () 返回前面那个子进程的
pid,他自己被称为“父进程”

程序 从 fork 开始分支 (称分支不准确), 一路是主进程 pid > 0 (pid 是子进程ID) 一路是子进程 pid == 0 自此分成两个任务
其实fork的时候已经两个分支了,数据段被复制了一份,因此pid有两份
执行pid=fork()时,返回值赋给pid在两个进程中运行,
fork会返回给父进程的那个>0的值,告诉调用者新建进程的pid
子进程的fork返回值是0
更不用说if...else的比较也是在两个进程中都做的了

二、无名管道

管道可以说是最古老的IPC形式,所谓管道,是指进程间建立的一条通信的通道,从本质上看,管道是UNIX文件概念的推广管道通信的介质是文件,先看一下管道的特点:

1.管道的特点:

(1)管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

(2)无名管道只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);后来发展了FIFO(也称有名管道)

(3)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

(4)数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

2.无名管道API及操作:

头文件:#include <unistd.h>

数据成员:int pipe_fd[2];

管道创建:int pipe(int fd[2])

该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。

管道读写:

管道两端可分别用描述字fd[0]以及fd[1]来描述,管道读端:fd[0],管道写端:fd[1];

读管道规则:

关闭管道的写端:close (fd[WRITE]);

读出:read(fd[READ],string,strlen(string));

读出后关闭管道的读端:close(fd[REAd]);

写管道规则:

关闭管道的读端:close(fd[REAd]);

写入:write(fd[WRITE],string,strlen(string));

写入后关闭管道的写端:close (fd[WRITE]);
三、有名管道fifo

FIFO
普通管道一般用于父子进程中,如果不是父子进程呢?
那么用命名管道(FIFO)
1.命名管道可以用于两个不相关的进程之间传输数据
2.命名管道在文件系统中是以文件的形式真实存在的,只不过比较特殊而已
3.当共享管道的进程执行完所有的I / O操作以后,这个管道文件还是存在的,知不是 里面什么数据也没有罢了,不过下次还是可以用的
mkfifo
int mkfifo(const char * pathname,mode_t mode);
另外

当使用open()来打开 FIFO文件时,O_NONBLOCK旗标会有影响
1、当使用O_NONBLOCK 旗标时,打开FIFO 文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO 文件来读取,则写入的操作会返回ENXIO 错误代码。
2、没有使用O_NONBLOCK 旗标时,打开FIFO 来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO 文件来读取后才正常返回。
返回值
若成功则返回0,否则返回-1,错误原因存于errno。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: