Linux进程间通信(一)

时间:2022-01-31 19:05:02

什么是进程间通信?

 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到所以进程之间要交换数据必须通过核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

利用管道实现进程间通信:

  管道是一一种最基本的IPC机制,由pipe函数创建:

  #include<unistd.h>

  int pipe(int filedes[2]);

  调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过filedes参数传出给用户程序两个件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记,就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]);向这个文件读写数据其实是在读写内核缓冲区.pipe函数调用成功返回0,调用失败返回-1。开辟了管道之后如何实现两个进程间的通信呢?

1. 父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。

2. 父进程调用用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。

3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里里写,子进程可以从管道里里读,管道是用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。

匿名管道的特点:

1.用于单向通信

2.用于具有血缘关系的两个进程

3.管道是基于文件的通过文件的描述符来访问

4.管道的生命周期随进程

5.管道提供的是面向字节流的服务

6.管道在内部提供了同步与互斥机制

简单的实现:

  1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<errno.h>
5 #include<sys/types.h>
6 #include<sys/wait.h>
7 #include<string.h>
8
9 int main()
10 {
11 int pipe_fd[2];
12 if(pipe(pipe_fd)<0)
13 {
14 printf("pipe error,%s\n",strerror(errno));
15 return 1;
16 }
17 pid_t id=fork();
18 if(id==0)
19 {
20 //child
21 //write
22 close(pipe_fd[0]);
23 char* msg=NULL;
24 int count=0;
25 while(count<10)
26 {
27 msg="hello,bit!";
28 write(pipe_fd[1],msg,strlen(msg)+1);
29 printf("child write hello bit success,%d\n",count++);
30 }
31 }
32 else
33 {
34 //father
35 //read
36 close(pipe_fd[1]);
37 char buf[1024];
38 int j=0;
39 memset(buf,'\0',sizeof(buf));
40 while(j<10)
41 {
42 sleep(1);
43 //memset(buf,'\0',sizeof(buf));
44 read(pipe_fd[0],buf,sizeof(buf));
45 //printf("%s\n",buf);
46 printf("father read msg from child:%s\n",buf);
47 j++;
48 }
49 }
50 return 0;
51 }

运行结果:

Linux进程间通信(一)