关于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。
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。
相关文章推荐
- 关于linux进程通信总结
- linux学习笔记:关于linux守护进程与终端的通信
- Linux下C语言编程入门-12关于进程之间的通信
- 关于Linux下进程间使用共享内存和信号量通信的时的编译问题
- linux进程之间通信
- linux下系统调用编程socket进程通信---(1)
- Linux进程间六种通信方式
- linux运行进程通信遇到问题及解决方法
- linux下多进程多线程之三通信
- 那年,一步一步学linux c ---关于进程等待~
- Linux进程通信之信号
- [置顶] 简单解析linux下进程通信方法
- Linux的进程/线程间通信方式总结
- Linux 进程通信之 ——信号和信号量总结
- Linux的进程/线程间通信方式总结
- Linux的进程/线程通信方式总结
- linux进程通信-有名管道
- linux进程间的通信(C): 使用信号量进行同步的共享内存机制
- Linux进程通信-管道(pipe)
- Linux进程间的通信