zoukankan      html  css  js  c++  java
  • O_NONBLOCK模式下写fifo的注意事项

    后台网络通信框架一般采用fifo来作为事件通知的机制:创建一个fifo,然后以非阻塞读和非阻塞写的方式打开fifo,然后把fd加到epoll里面,作为通知网络事件的fd.

    在这里有个隐晦的问题容易被忽视.fifo在以非阻塞模式打开时,必须先打开读,然后打开写.不然会报错No such device or address.即如下代码所示是正确的

    #define FIFO_FILE "/tmp/fifo.xxx"
    #define FIFO_MODE FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
    
    mkfifo(FIFO_FILE, FIFO_MODE);
    int readfd  = open(FIFO_FILE, O_RDONLY | O_NONBLOCK, 0);
    int writefd = open(FIFO_FILE, O_WRONLY | O_NONBLOCK, 0);

    上述代码中的两个open不能反过来,不然会报错: No such device or address

    注意到这种情况,那即使以后我们写代码是在两个进程间通过fifo来通信,也不用关心以写的方式打开fifo之前,fifo是否已经以读的方式打开,因为我们可以设置一个dummy fd,如下所示:

    int dummyfd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK, 0);
    int writefd = open(FIFO_FILE, O_WRONLY | O_NONBLOCK, 0);

    敢兴趣的朋友可以把下面的代码复制过去,看看输出结果:

    1/注释L18

    2/不注释L18

     1 #include <unistd.h>                                                                                 
     2 #include <sys/types.h>                                                                              
     3 #include <sys/stat.h>                                                                               
     4 #include <fcntl.h>                                                                                  
     5                                                                                                     
     6 #include <errno.h>                                                                                  
     7 #include <stdio.h>                                                                                  
     8 #include <string.h>                                                                                 
     9                                                                                                     
    10 #define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH                         
    11 #define FIFO_FILE "/tmp/fifo.test_nonblock_write"                                                   
    12                                                                                                     
    13 int main(void)                                                                                      
    14 {                                                                                                   
    15     mkfifo(FIFO_FILE, FILE_MODE);                                                                   
    16     fprintf(stderr, "mkfifo, errno=%d, error=%s
    ", errno, strerror(errno));                        
    17                                                                                                     
    18     //open(FIFO_FILE, O_RDONLY|O_NONBLOCK, 0);                                                      
    19     fprintf(stderr, "open(O_RDONLY), errno=%d, error=%s
    ", errno, strerror(errno));                
    20                                                                                                     
    21     open(FIFO_FILE, O_WRONLY|O_NONBLOCK, 0);                                          
    22     fprintf(stderr, "open(O_WRONLY), errno=%d, error=%s
    ", errno, strerror(errno));                
    23                                                                                                     
    24     unlink(FIFO_FILE);                                                                          
    25                                                                                                     
    26     return 0;                                                                                       
    27 }
  • 相关阅读:
    【链接】idea没有svn
    移动端适配解决方案
    项目中多个文件引入同一份公共样式less文件导致编译打包后有多份样式
    2020最新编辑器集成eslint、prettier、stylelint,git提交预检查代码配置
    eslint+prettier学习
    artTempate模版继承父模版之后再引入子模版不生效?
    iOS底层原理开篇
    iOS应用千万级架构:安全与加密
    使用RabbitMQ实现延迟任务
    JAVA三元运算符空指针引用的坑
  • 原文地址:https://www.cnblogs.com/i4oolish/p/4374952.html
Copyright © 2011-2022 走看看