• 进程间通信___命名管道(FIFO)


    命名管道(FIFO)

    基本概念

    命名管道和一般的管道基本相同,但也有一些显著的不同:

        命名管道是在文件系统中作为一个特殊的设备文件而存在的。

        不同祖先的进程之间可以通过管道共享数据。

        当共享管道的进程执行完所有的I/O操作以后,命名管道将继续保存在文件系统中以便以后使用。

    管道只能由相关进程使用,它们共同的祖先进程创建了管道。但是,通过FIFO,不相关的进程也能交换数据。

     

    命名管道创建和操作::

    #include

    #include

    int mkfifo(const char *pathname, mode_t mode);

    返回:若成功则为0,若出错则为-1

    一旦已经用mkfifo创建了一个FIFO,就可用open打开它。确实,一般的文件I/O函数(closereadwriteunlink)都可用于FIFO

    当打开一个FIFO时,非阻塞标志(O_NONBLOCK)产生下列影响:

    (1)     在一般情况中(没有说明O_NONBLOCK),只读打开要阻塞到某个其他进程为写打开此FIFO。类似,为写而打开一个FIFO要阻塞到某个其他进程为读而打开它。

    (2)     如果指定了O_NONBLOCK,则只读打开立即返回,但是,如果没有进程已经为读而打开一个FIFO,那么只写打开将出错返回,其errnoENXIO

    类似于管道,若写一个尚无进程为读而打开的FIFO,则产生信号SIGPIPE。若某个FIFO的最后一个写进程关闭了该FIFO,则将为该FIFO的读进程产生一个文件结束标志。

    FIFO相关出错信息:

    EACCES                                                             (无存取权限)

    EEXIST                                                               (指定文件不存在)

    ENAMETOOLONG                                         (路径名太长)

    ENOENT                                                           (包含的目录不存在)

    ENOSPC                                                            (文件系统剩余空间不足)

    ENOTDIR                                                           (文件枯井无效)

    EROFS                                                                (指定的文件存在于只读文件系统中)

     

    fifo_read.c文件内容如下:

     

    #include

    #include

    #include

    #include

    #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 ”);

    printf(“Preparing for reading bytes… ”);

     

    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 ”);

    }

             printf(“read %s from FIFO ”,buf_r);

             sleep(1);

    }

    pause();

    unlink(FIFO);

    }

     

    fifo_write.c文件内容如下:

     

    #include

    #include

    #include

    #include

    #include

    #include

    #define FIFO_SERVER “/tmp/myfifo”

     

    main(int argc, char **argv)

    {       

             int fd;

    char w_buf[100];

             nt nread;

     

             if(fd==-1)

    if(error==ENXIO)

             printf(“open error;no reading process ”

    fd=open(FIFO_SERVER, O_WRONLY|O_NONBLOCK,0);

    if(argc==1)

             print(“please send something ”)

    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 ”);

    }

    else

    {       

             printf(“write %s to the FIFO ”, w_buf);

    }

     

    gcc –o fifo_read fifo_read.c

    gcc –o fifo_write fifo_write.c

     

    运行结果:

    读管道:

    ./fifo_read

    Preparing for reading bytes…

    read from FIFO

    read from FIFO

    read from FIFO

    read from FIFO

    read from FIFO

    read from FIFO

     

    写管道:

    ./fifo_write ccccccccccc

    write ccccccccccc to the FIFO

    读管道:

    read from FIFO

    read from FIFO

    read from FIFO

    read from FIFO

    read ccccccccccc from FIFO

    read from FIFO

    read from FIFO

    read from FIFO


  • 相关阅读:
    【LeetCode】Set Matrix Zeroes 解题报告
    CodeForces 14 E
    Linux守护进程的编程实现
    用fildder 查看loveuv 刷流量时通信的数据
    .NET MVC学习笔记(一)
    微价值:专訪《甜心爱消除》个人开发人员Lee,日入千元!
    JSP动作--JSP有三种凝视方式
    【Hibernate步步为营】--映射合集汇总
    阿里好的开源项目有哪些(善用工具)
    色彩搭配原理与技巧?
  • 原文地址:https://www.cnblogs.com/songfeixiang/p/3733854.html
Copyright © 2020-2023  润新知