进程间通信&匿名管道

目录

1.进程间通信目的

1.1为什么需要进程通信呢?

1.2常见的进程间通信方式:

2.管道(匿名管道):

2.1管道符号 |

2.1管道的本质

 2.3 管道的接口

2.3.1理解参数的含义

2.3.2 从PCB角度理解匿名管道

 2.3.3用匿名管道进行读写

 2.3.4进程间通信


1.进程间通信目的

1.1为什么需要进程通信呢?

每一个进程的数据都是存储在物理内存当中,进程通过各自的进程虚拟地址空间进行访问,访问的时候,通过各自的页表的映射关系,访问到物理内存。
从进程的角度看,每个进程都认为自己拥有4G的空间,至于物理内存当中数据如何存储,页表如何映射,进程是不清楚。 这也造就了进程的独立行。
进程独立性:
好处:让每一个进程在运行的时候,都是独立进行运行的,数据不会窜。
坏处:如果两个进程之间需要数据交换,那么由于进程独立性,就没有那么方便了。
所以:进程间通信本质上是进程和进程之间交换数据的手段。

数据传输:一个进程需要将它的数据发送给另一个进程。
资源共享:多个进程之间共享同样的资源。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止 时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另 一个进程的所有陷入和异常,并能够及时知道它的状态改变。

1.2常见的进程间通信方式:

管道/共享内存/消息队列/信号量/信号/网络
网络是最大的,使用最广泛的进程间通信方式。

2.管道(匿名管道):

2.1管道符号 |

ps aux | grep [ 搜索的内容]

2.1管道的本质

管道在内核当中就是一块缓冲区,供进程进行读写,交换数据

例如:ps aux | grep [ 搜索的内容]

 2.3 管道的接口

2.3.1理解参数的含义

创建匿名管道,本质上就是在内核创建出来一个缓冲区。
int pipe(int pipefd[2]);
参数:参数为出参(输出型参数),也就是pipefd的值是pipe函数进行填充的,调用者进行使用
pipefd是数组,有两个元素
pipefd[0] :管道的读端
pipefd[1] :管道的写端
返回值:
0:创建成功
-1:创建失败

#include <stdio.h>
#include <unistd.h>

int main(){
    int pipefd[2];
    int ret=pipe(pipefd);
    if(ret < 0){
     perror("pipe:");
    }
    //创建成功
    
    printf("pipefd[0]=%d\n",pipefd[0]);
    printf("pipefd[1]=%d\n",pipefd[1]);
    while(1){
        sleep(1);
    }
    return 0;
}

 pipefd[0] ,pipefd[1] 其实是文件描述符

2.3.2 从PCB角度理解匿名管道

 2.3.3用匿名管道进行读写

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
    int pipefd[2];
    int ret=pipe(pipefd);
    if(ret < 0){
     perror("pipe:");
    }
    //创建成功
    
    printf("pipefd[0]=%d\n",pipefd[0]);
    printf("pipefd[1]=%d\n",pipefd[1]);
    char content[]="study hard!";
    write(pipefd[1],content,strlen(content));

    char buf[1024];
    read(pipefd[0],buf,sizeof(buf)-1);
    printf("%s\n",buf);
    //while(1){
     //   sleep(1);
    //}
    return 0;
}

 2.3.4进程间通信

不同的进程,要用同一个匿名管道进行通信,则需要进程拥有该管道的读写两端的文件描述符。

场景1:

pipe.c:

#include <stdio.h>
#include <unistd.h>

int main(){
    int pipefd[2];
    int ret=pipe(pipefd);
    if(ret < 0){
     perror("pipe:");
    }
    while(1){
        sleep(1);
    }
    return 0;
}

test.c:

#include <stdio.h>
#include <unistd.h>

int main(){
    while(1){
        sleep(1);
    }
    return 0;
}


pipe进程有匿名管道的读写两端,但是test进程进程没有,所以pipe进程和test进程没有办法通过匿名管道进行通信。

场景2:

pipe.c

#include <stdio.h>
#include <unistd.h>

int main(){
    int pipefd[2];
    int ret=pipe(pipefd);
    if(ret < 0){
     perror("pipe:");
    }
    while(1){
        sleep(1);
    }
    return 0;
}

test.c

#include <stdio.h>
#include <unistd.h>

int main(){
    int pipefd[2];
    int ret=pipe(pipefd);
    if(ret < 0){
        perror("pipe:");
    }
    while(1){
        sleep(1);
    }
    return 0;
}

两个不同的进程,创建了各自的匿名管道,但这两个进程之间也不能进行进程间通信。

往下看哦,还没完!

猜你喜欢

转载自blog.csdn.net/sy2453/article/details/123549856