目录
进程间通信的目的:
- 数据传输:一个进程需要将它的数据发送给另一个进程
- 资源共享:多个进程之间共享同样的资源
- 通知事件:一个进程需要向另一个或一组进程发送消息,通知他们发生了某种事情
- 进程终止:有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有陷入和异常,并且能够及时知道它的状态改变。
进程间通信的本质是:让不同的进程看到公共的资源。
进程间通信分类
管道
- 匿名管道
- 命名管道
System V IPC
- System V 消息队列
- System V 共享内存
- System V 信号量
POSIX IPC
- 消息队列
- 共享内存
- 信号量
- 互斥量
- 条件变量
- 读写锁
管道
管道是文件,文件类型中以p开头的就是管道文件。
管道的本质:让两个不同的进程看到一个公共的管道。
管道是最常用的通信方式,我们把从一个进程连接到另个进程的一个数据流称为一个“管道”。
匿名管道
#include<unistd.h>
int pipe(int fd[2]);
功能:创建一个无名管道
参数:文件描述符数组,其中fd[0]表示读端,fd[1]表示写端,传出来的值是 3 ,4。0可以看成嘴巴,1可以看成笔
返回值:成功返回0,失败返回错误代码(-1)。
用fork来共享管道原理
一个进程可以打开多个文件,一个文件也可以被多个进程打开。
1.首先父进程调用pipe函数,创建管道;
2.父进程fork(),子进程继承父进程的数据结构,子进程并不会拷贝文件,但是fd_arrry会拷贝,fd_arrry属于进程,文件并不属于;
3.父进程关闭fd[0],子进程关闭fd[1],管道是单向通信的,如果想要双向通信,就只有创建两个管道。
下面代码实现
#include<unistd.h>
功能:创建一个无名管道
int pipe(int fd[2]);
参数:fd:文件描述符数组,其中fd[0]表示读端,fd[1]表示写端。
返回值:成功返回0,失败返回错误代码<0
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
int main ()
{
int fds[2];
if(pipe(fds)<0){
printf("pipe error\n");
return 1;
}
//printf("fds[0]: %d, fds[1]: %d\n", fds[0], fds[1]);
pid_t id = fork();
if(id==0)
{
//child w
close(fds[0]);
const char *str = "I am a student \n";
int i = 5;
while(i--)
{
write(fds[1],str,strlen(str));
printf("child write done...\n");
sleep(1);
}
close(fds[1]);
exit(0);
}else{
//parent r
close(fds[1]);
char buff[1024];
while(1)
{
ssize_t s = read(fds[0],buff,sizeof(buff)-1);
if(s>0){
buff[s] = 0;
printf("parent recv done : %s",buff