• Linux 进程间通信 管道通信


    先进先出的文件  

    写入数据的是管道的尾部,读出数据的是管道的头部。   管道可以分为两种,有名管道FIFO,无名管道pipe。

    一、无名管道

      只能用于父进程和子进程的通信。只能有 pipe() 创建

    	int pipe_fd[2];
    	pipe(pipe_fd)

      使用pipe时,会创建2个文件描述符: 

          pipe_fd[0] 用于读管道  , pipe_fd[1] 用于写管道。

     使用close(fd)  即可关闭。

      通常使用fork()之前调用pipe() ,否则子进程不会继承父进程的  管道。

    #include <unistd.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    /*创建管道*/
    int main()
    {
        int pipe_fd[2];
        if(pipe(pipe_fd)<0)
        {
        printf("pipe create error\n");
        return -1;
        }
        else 
            printf("pipe create success\n");
        close(pipe_fd[0]);
        close(pipe_fd[1]);
    }
    View Code

     父进程往进写,子进程往出读

    #include <unistd.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int pipe_fd[2];
        pid_t pid;
        char buf_r[100];
        char* p_wbuf;
        int r_num;
        
        memset(buf_r,0,sizeof(buf_r));
        
        /*创建管道*/
        if(pipe(pipe_fd)<0)
        {
            printf("pipe create error\n");
            return -1;
        }
        
        /*创建子进程*/
        if((pid=fork())==0)  //父进程>0   ,子进程==0
        {
            printf("\n");
            close(pipe_fd[1]);  //  关闭写的文件
            sleep(2); /*为什么要睡眠*/
            if((r_num=read(pipe_fd[0],buf_r,100))>0)
            {
                printf(   "%d numbers read from the pipe is %s\n",r_num,buf_r);
            }    
            close(pipe_fd[0]);
            exit(0);
          }
        else if(pid>0)
        {
            close(pipe_fd[0]);
            if(write(pipe_fd[1],"Hello",5)!=-1)
                printf("parent write1 Hello!\n");
            if(write(pipe_fd[1]," Pipe",5)!=-1)
                printf("parent write2 Pipe!\n");
            close(pipe_fd[1]);
            sleep(3);
            waitpid(pid,NULL,0); /*等待子进程结束*/
            exit(0);
        }
        return 0;
    }

    二、有名管道  FIFO

      可以用于任意两个进程间的通信。

    mkfifo(/tmp/myfifo,O_CREAT|O_EXCL)//路径,文件的操作

    使用FIFO时,O_NONBLOCK的作用:

      1.不使用此参数,要求不满足则进程处于阻塞态,如FIFO是空的时,进程将阻塞

      2.使用此参数,要求不满足则进程不阻塞,出错立刻返回,error是ENXIO

      历程创建一个FIFO,一个读一个写

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define FIFO_SERVER "/tmp/myfifo"
    
    main(int argc,char** argv)
    {
        int fd;
        char w_buf[100];
        int nwrite;
            
        /*打开管道*/
        fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
        
        if(argc==1)
        {
            printf("Please send something\n");
            exit(-1);
        }
        
        strcpy(w_buf,argv[1]);
        
        /* 向管道写入数据 */
        if((nwrite=write(fd,w_buf,100))==-1)
        {
            if(errno==EAGAIN)
                printf("The FIFO has not been read yet.Please try later\n");
        }
        else 
            printf("write %s to the FIFO\n",w_buf);
    }
    View Code
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define FIFO "/tmp/myfifo"
    
    main(int argc,char** argv)
    {
        char buf_r[100];
        int  fd;
        int  nread;
        
        /* 创建管道 */
        if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
            printf("cannot create fifoserver\n");
        
        printf("Preparing for reading bytes...\n");
        
        memset(buf_r,0,sizeof(buf_r));
        
        /* 打开管道 */
        fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
        if(fd==-1)
        {
            perror("open");
            exit(1);    
        }
        while(1)
        {
            memset(buf_r,0,sizeof(buf_r));
            
            if((nread=read(fd,buf_r,100))==-1)
            {
                if(errno==EAGAIN)
                    printf("no data yet\n");
            }
            printf("read %s from FIFO\n",buf_r);
            sleep(1);
        }    
        pause(); /*暂停,等待信号*/
        unlink(FIFO); //删除文件
    }
    View Code
  • 相关阅读:
    PHP垃圾回收深入理解
    PHP的运行机制与原理(底层)
    SSO单点登录-简单实现
    HBuilder 打包流程
    PHP实现多继承的效果(tarits)
    mysql explain用法和结果的含义
    mysql分区功能详细介绍,以及实例
    MySQL分表、分区

    椒图
  • 原文地址:https://www.cnblogs.com/hkyst/p/7677175.html
Copyright © 2020-2023  润新知