目录
进程间通信介绍
进程通信(Interpeocess communication)简称IPC;所谓进程间通信就是两个相互独立的进程之间完成交互工作,我们在之前学习到的所有的程序都是进程,他们之间相互独立,那么他们之间是怎么完成交互工作的呢,就比如你和你的微信好友是怎么发信息聊天的呢?
进程间通信的目的
- 数据传输:一个进程将自己的数据发送给另外一个进程
- 资源共享:多个进程之间享受同样的资源
- 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
- 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变
进程间通信发展与分类
- 管道
- System V进程间通信
- POSIX进程间通
管道
- 匿名管道
- 命名管道
System V进程间通信
- System V 消息队列
- System V 共享内存
- System V 信号量
POSIX IPC
- 消息队列
- 共享内存
- 信号量
- 互斥量
- 条件变量
- 读写锁
管道
管道概念
管道是unix中最原始的进程之间通信的方式
我们把一个进程连接到另一个进程的数据流称为管道
通过这个|我们可以查看code.c这个文件包含了多少行代码。但是cat和wc是两个进程,这就完成两个进程之间的互动,cat进程将查看代码数量命令通过管道交给wc进程
匿名管道:
通过pipe函数创建一个匿名管道:
int pipe(int id[2]);
参数解读:
id:文件描述符数组,id【0】表示读端,id【1】表示写端,创建成功返回0,失败返回错误代码
用户可以指定关闭或者打开管道的读端或者写端,比如让父进程读取,子进程写入~
注意:匿名管道只用于父子进程之间交换资源~
父子进程控制管道原理
父子进程被创建之后进程PCB当中都有了一个指针数组,struct file_struct,这个是用来描述组织文件的。而且父子进程都拥有这个指针数组,而且子进程继承了父进程的数据的。所以子进程就会和父进程拥有同样的数据并且指向相同的空间。在创建好管道要完成父子间通信的时候,父子进程同时指向这个文件,父进程想要对文件进行写入操作,会先将数据写入到文件缓冲区当中,而不是直接写入然后就打印到屏幕上了。结论:对于程序的操作当中,所发送的命令并不是立即执行,而是存入到相对应的缓冲区当中,在合适的时候再完成相应命令~
#include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<string.h>
5 int main()
6 {
7 int pipefd[2]={0};
8 //pipef为一个输出型参数 我们可以通过这个参数读取到打开的两个fd
9 if(pipe(pipefd)!=0)
10 {
11 perror("pipe error\n");
12 return 1;
13 }
14 printf("pipefd[0]:%d\n",pipefd[0]);
15 printf("pipefd[1]:%d\n",pipefd[1]);
16 //创建父子进程完成他们之间的通信工作
17 if(fork()==0)
18 {
19 close(pipefd[0]);
20 const char*msg="hello world";
W> 21 int count=0;
22 while(1)
23 {
24 write(pipefd[1],msg,strlen(msg));
25 //write(pipefd[1],"a",1);
26 //printf("child:%d\n",count);
27 //count++;
28 sleep(1);
29 }
30 exit(0);
31 }
32 close(pipefd[1]);
33 while(1)
34 {
35 sleep(1);
}
30 exit(0);
31 }
32 close(pipefd[1]);
33 while(1)
34 {
35 sleep(1);
36 char c[1024*2]={0};
37