进程间通信---管道

我们知道,进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间却是“公共场所”,所以内核显然可以提供这样的条件。所以进程之间交换数据时在内核进行,通俗的说A进程把数据拷贝到内核,B进程从内核中把数据读走,我们把内核提供的这种机制叫做进程间通信,(IPC)。

一、管道(pipe)
管道是Unix中最古老的进程间通信的形式。 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。

管道是一种基本的ipc机制,由pipe函数创建,如下:

调用pipe函数时在内核中开辟一块缓冲区(管道)用于通信,它有一个读端和一个写端。
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
pipe函数调用成功返回0,失败返回-1。

二、如何实现进程间通信
这里写图片描述

这里写图片描述

这里写图片描述

(1)首先父进程调用pipe开通管道,得到两个文件描述符指向管道的两端
(2)父进程通过fork创建子进程,那么同样的子进程也有两个文件描述符指向管道的两端
(3)父进程关闭fd[0],子进程关闭管道fd[1],这样父进程向管道写数据,子进程向管道读数据,这就实现了进程的通信.
注:图中0、1、2分别指的是标准输入,标准输出,标准出错

三、匿名管道和命名管道
1、匿名管道
值得说明的是,匿名管道只能实现亲缘关系进程之间通信,而不能实现任意两个本地进程之间的通信
使用,正如上图所示:
在父进程中,首先创建这个匿名管道,然后fork创建子进程,关闭子进程的读端,子进程只能进行写,子进程向这个匿名管道里面写数据,父进程向这个匿名管道里面读数据,以此来实现进程间的通信。

实现:

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main()
{
 int fds[2] ={0};
    if(pipe(fds)<0)
    {
        perror("pipe");
        return 1;
    }
    pid_t id =fork();
    if(id==0)
    {
        //子进程写
        close(fds[0]);
     char *msg ="hello pipe,i am a child!";
        while(1)
        {
            write(fds[1],msg,strlen(msg));
            sleep(1);
        }
        exit(0);//退出
    }
    else{
        //父进程读
        close(fds[1]);
        char buf[1024];
        while(1)
        {
            ssize_t ret = read(fds[0],buf,sizeof(buf)-1);
            if(ret>0)
            {
                buf[ret-1]=0;
                printf("client->father:%s\n",buf);
            }
        }
        pid_t tmp =wait(NULL);
    }
 return 0;
}

这里写图片描述

2、命名管道
如果想在不相关的进程之间通信,可以使用FIFO文件来做这项工作,它经常被称为命名管道 。
FIFO总是按照先进先出的原则工作,也就是第一个被写入的数据将首先从管道中读出 。
那么如何创建呢?

方法一:命名管道可以从命令行创建,方法是使用命令:
$ mkfifo filename
方法二:从在程序使用系统函数创建,函数有:
int mkfifo(const char *filename,mode_t mode);
以mkfifo为例:

int main(int argc, char *argv[]) 
{   
    mkfifo("p2", 0644);   
    return 0;
}

eg-用命名管道实现server&client通信 :
(1)、编写Makefife文件:
这里写图片描述
(2)、server.c用来读数据(读端)
这里写图片描述
(3)、client.c向管道写数据(写端):
这里写图片描述
结果:
这里写图片描述

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值