• 【APUE】进程间通信之管道


    管道是UNIX系统IPC最古老形式,并且所有UNIX系统都提供此种通信机制。管道由下面两种局限性:

    1)历史上,它们是半双工的(即数据只能在一个方向上流动)

    2)它们只能在具有公共祖先的进程之间使用。通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道

    管道由调用pipe函数创建:

    #include <unistd.h>

    int pipe(int filedes[2]);//若成功则返回0,出错返回-1

    注意:filedes[0]为读而打开,filedes[1]为写而打开,filedes[1]的输出是fileds[0]的输入

    单个进程中的管道几乎没有任何作用。通常,调用pipe的进程接着调用fork,这样就创建了从父进程到子进程(或反向)的IPC通道。

    调用fork后做什么取决于我们想要有的数据流的方向。对于从父进程到子进程的管道,父进程关闭管道的读端(fd[0]),子进程则关闭写端(fd[1]).

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #define MAXLINE 100
    //经由管道父进程向子进程传送数据
    int main()
    {
            int n;
            int fd[2];
            pid_t pid;
            char line[MAXLINE];
    
            if(pipe(fd)<0)
                    printf("pipe error");
            if((pid=fork())<0)
                    printf("fork error");
            else if(pid>0)
            {
                    close(fd[0]);
                    write(fd[1],"hello world
    ",12);
            }
            else
            {
                    close(fd[1]);
                    n=read(fd[0],line,MAXLINE);
                    write(STDOUT_FILENO,line,n);
            }
            exit(0);
    }

    采用管道实现双向通信需要两个管道,控制两个不同的数据流向。现在模拟一个Client和Server双向通信的过程,Client与Server之间 可以相互发送和接收信息。此时需要两个管道进行模拟,管道1模拟Server写Client读数据流向,管道2模拟Client写Server读数据流 向。代码如下所示:

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<errno.h>
    #include<string.h>
    
    int main()
    {
        int fd1[2],fd2[2];
        pid_t childpid;
        char buf[100];
    
        memset(buf,0,100);
    
        if(pipe(fd1)==-1)
        {
            perror("pipe()error");
            exit(-1);
        }
        if(pipe(fd2)==-1)
        {
            perror("pipe() error");
            exit(-1);
        }
        childpid=fork();
        if(childpid==0)
        {
            printf("server input a message:");
            gets(buf);
            close(fd1[0]);
            close(fd2[1]);
            write(fd1[1],buf,strlen(buf));
            read(fd2[0],buf,100);
            printf("server received message from client:%s
    ",buf);
            exit(0);
        }
        if(childpid==-1)
        {
            perror("fork()error");
            exit(-1);
        }
        close(fd1[1]);
        close(fd2[0]);
        read(fd1[0],buf,100);
        printf("client received a message from server:%s
    ",buf);
        printf("client input a message:");
        gets(buf);
        write(fd2[1],buf,strlen(buf));
        waitpid(childpid,NULL,0);
        return 0;
    }
  • 相关阅读:
    iscsi一致性的测试验证方法
    ceph各个版本之间参数变化分析
    rgw的rgw_thread_pool_size配置调整
    rgw前端替换civetweb为beast
    配置内网访问的TV
    关于vm.min_free_kbytes的合理设置推测
    rbd的删除回收站功能
    python爬取微博热门话题榜
    Selenium+Pytest自动化测试框架—禅道实战
    python带参数装饰器的两种写法
  • 原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/3855093.html
Copyright © 2020-2023  润新知