进程通信 - 管道通信

  在创建子进程的时候,会将父进程中的资源复制一份给子进程,然后他们各自使用自己的资源,那如果父进程想与子进程通信,如何达到呢,如果说采用套接字的方法,那未免太慢了,是否可以创建一个共同使用的内存,双方都可以进行访问呢,这样子进程要给父进程的数据,放到这块内存,父进程直接拿就可以了。操作系统就实现了这种机制,来支持进程之间进行通信。

管道实现进程间通信

  操作系统为进程间通信提供了管道这一内存工具,管道属于操作系统,就像套接字一样,他是不属于进程的(进程只是拥有对应于套接字的文件描述符,而非套接字)。这样,在使用fork函数创建子进程时,就无法复制管道了。通过下列函数可以创建管道:

#include <unistd.h>

int pipe(int fuledes[2]);	// 创建成功返回0,失败返回-1

父进程中调用该函数,然后通过传入一个长度为2的数组,来创建管道,分别保存用来读的文件描述符和用来写的文件描述符。一般来说,0用来读,1用来写。接下来看看具体如何使用管道:

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

#define BUF_SIZE 30

int main(int argc, char *argv[])
{
    int fds[2];             // 用来保存文件描述符
    char str[] = "hello world!";
    pid_t pid;

    pipe(fds);              // 创建管道
    pid = fork();
    if(pid == 0)
    {
        write(fds[1], str, sizeof(str));
    }
    else
    {
        char buf[BUF_SIZE];
        read(fds[0], buf, BUF_SIZE);
        puts(buf);
    }
    return 0;
}

运行结果如下:
请添加图片描述
现在只是实现了单向的一个通信,那单条管道是否可以实现双向的通信呢,此处我们尝试一下:

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

#define BUF_SIZE 30

int main(int argc, char *argv[])
{
    int fds[2];             // 用来保存文件描述符
    char str1[] = "hello world!";
    char str2[] = "who are you?";
    char buf[BUF_SIZE];
    pid_t pid;

    pipe(fds);              // 创建管道
    pid = fork();
    if(pid == 0)
    {
        write(fds[1], str1, sizeof(str1));
        read(fds[0], buf, BUF_SIZE);
        printf("child process output: %s \n", buf);
    }
    else
    {
        read(fds[0], buf, BUF_SIZE);
        printf("parent process output: %s \n", buf);
        write(fds[1], str2, sizeof(str2));
    }
    return 0;
}

运行结果如下:
请添加图片描述
  子进程写入消息后,子进程先将消息读取了出来,然后父进程由于其中已经没有消息可读,阻塞在read函数处。也就是说写入管道的消息,可能由于非指定对象读取,而导致被我们不想让读取的文件描述符获取到这个信息。

  当然我们可以在子进程写入消息后,为其设置一个睡眠时间,从而让父进程先读取这个消息,但是实际编程中,如果进程过多,这种设置方法未免太过耗费精力,且影响系统性能。所以我们可以通过设置两条管道,一条用来子进程读父进程写,一条用来父进程读子进程写。

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

#define BUF_SIZE 30

int main(int argc, char *argv[])
{
    int fds1[2], fds2[2];             // 用来保存文件描述符
    char str1[] = "hello world!";
    char str2[] = "who are you?";
    char buf[BUF_SIZE];
    pid_t pid;

    pipe(fds1), pipe(fds2);              // 创建管道
    pid = fork();
    if(pid == 0)
    {
        write(fds1[1], str1, sizeof(str1));
        read(fds2[0], buf, BUF_SIZE);
        printf("child process output: %s \n", buf);
    }
    else
    {
        read(fds1[0], buf, BUF_SIZE);
        printf("parent process output: %s \n", buf);
        write(fds2[1], str2, sizeof(str2));
    }
    return 0;
}

运行如下:
请添加图片描述
这样就实现了进程间的双向通信。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值