zoukankan      html  css  js  c++  java
  • pipe/popen/fifo

    pipe(管道)

    • 专用于父子进程通信, 函数原型 int pipe(int fd[2])
    • fd[0]表示输入, fd[1]表示输出
    • 如果父子进程要双向通信, 可以通过类似信号的功能进行控制, 也可以简单地打开两个pipe

    以下例子, 打开两个pipe, 第一个pipe用于父进程向子进程发送信息, 第二个pipe用于子进程向父进程发送消息
    子进程接收到消息后, 将消息转成大写然后发送给父进程

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <ctype.h>
     
    char *strupr(char *str){
        char *orign=str;
        for(;*str != 0;++str)
            *str=toupper(*str);
        return orign;
    }
    void err_quit(const char *str){
        perror(str);
        exit(1);
    }
    int main(){
        int n;
        int fd1[2], fd2[2];
        pid_t pid;
        char line[1024];
     
        if(pipe(fd1)<0 || pipe(fd2)<0)
            err_quit("pipe error");
     
        if((pid =fork())<0){
            err_quit("pipe error");
        }else if(pid >0 ){
            close(fd1[0]);
            close(fd2[1]);
            write(fd1[1],"hello world
    ",12);
            n=read(fd2[0],line,1024);
            write(STDOUT_FILENO,line,n);
        }else{
            close(fd1[1]);
            close(fd2[0]);
            n=read(fd1[0],line,1024);
            write(STDOUT_FILENO,line,n);
            line[n]='';
            write(fd2[1],strupr(line),n);
        }
        exit(0); 
    }
    

    popen和pclose

    • 函数原型FILE *popen(const char *cmdstring, const char *type) , type的参数为"r"或"w"
    • 用于父子进程通信, popen会自动fork子进程、创建pipe和关闭不需要的pipe端
    • popen的实现有可理解为execl("/bin/sh","sh","-c",cmdstring,NULL)
    • 当父进程向子进程发送信息时(type="w"), 实际就是向shell发送命令;
      当父进程从子进程获取信息时(type="r"), 实际就是读取shell的执行结果
    • 虽然popen的返回是FILE,但关闭是要用pclose(fp)
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
     
    #define MAXLINE 1024
    void err_quit(const char *str){
        perror(str);
        exit(1);
    }
    int main(){
        char line[MAXLINE];
        FILE *fpin;
     
        if((fpin=popen("ls -l","r")) == NULL)
            err_quit("popen error");  
        while(fgets(line,MAXLINE,fpin) != NULL){
            if(fputs(line,stdout) ==EOF)
                err_quit("fputs error");
        }
        if(ferror(fpin))
            err_quit("fpin error");
        if(pclose(fpin)==-1)
            err_quit("pclose error");
        return 0;
    }
    

    fifo

    • int mkfifo(const char *pathname,mode_t mode), 创建一个通信文件, 参数同open
    • mkfifo后, 以open打开文件, 打开方式为只读或只写, 另外可以非阻塞方式打开
    • 以只读打开时, 函数会阻塞直到有进程以只写方式打开
    • 以只写打开时, 函数会阻塞直到有进程以只读方式打开
    • 可用于非父子进程通信, 双向通信时开需两个
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    #define FILE_MODE S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IROTH
    void err_quit(const char *str){
        perror(str);
        exit(1);
    }
    int main(){
        char *pathname="./fifobuf";
        pid_t pid;
     
        if(mkfifo(pathname,FILE_MODE)<0)
            err_quit("mkfifo error");
     
        if((pid=fork())<0){
            err_quit("fork error");
        }else if(pid >0){
            int fd;
            if((fd=open(pathname,O_RDONLY))<0)
                err_quit("open error");
            char buf[100];
            int n;
            if((n=read(fd,buf,100)) < 0)
                err_quit("read error");
            buf[n]=0;
            puts(buf);
            exit(0);
        }else{
            int fd;
            if((fd=open(pathname,O_WRONLY))<0)
                err_quit("open error");
            char *str="hello world";
            write(fd,str,strlen(str));
            exit(0);
        }
    
  • 相关阅读:
    noip2001统计单词个数
    查看大图 zoomImage
    图片懒加载 lazyload
    ANSI_NULLS 和 QUOTED_IDENTIFIER
    Framewrok损坏导致卸载不了的解决办法
    kindeditor 上传图片 显示绝对 路径
    Could not load file or assembly 'MagickNet.dll'
    sql server 复制 需要有实际的服务器名称才能连接到服务器……
    iisapp 命令 弹出 iisschlp.wsc [88,25] 属性值无效 progid
    IIS 301重定向 报错 地址后面有eurl.axd
  • 原文地址:https://www.cnblogs.com/cfans1993/p/5657478.html
Copyright © 2011-2022 走看看