• fcntl函数 非阻塞轮询


     

    fcntl() 在打开的文件描述符 FD 上执行下面描述的操作之一。 操作由 cmd 确定。

    fcntl() 可以采用可选的第三个参数。 是否需要此参数由 cmd 确定。 所需的参数类型在后面的括号中指示。


    每个cmd名称(在大多数情况下,所需的类型是int,我们使用名称arg来标识参数),或者如果不需要参数,则指定void。

    下图是对是否需要设置可变参数的解释:

     

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. void SetNonBlock(int fd)
    9. {
    10.     // 提取文件描述符属性(返回值是一个位图)
    11.     int f1 = fcntl(0, F_GETFL);
    12.     if (f1 < 0)
    13.     {
    14.         perror("fcntl");
    15.         return;
    16.     }
    17.     // 使用F_SETFL将文件描述符设置回去,加上O_NONBLOCK参数。
    18.     fcntl(0, F_SETFL, f1 | O_NONBLOCK);
    19. }
    20. int main()
    21. {
    22.     char buffer[1024];
    23.     SetNonBlock(0); // 设置非阻塞。
    24.     while (true)//轮询
    25.     {
    26.         sleep(1);
    27.         printf(">>> ");
    28.         fflush(stdout);
    29.         ssize_t n = read(0, buffer, sizeof(buffer) - 1); // (检查条件是否就绪)等+拷贝
    30.         if (n > 0)
    31.         {
    32.             buffer[n - 1] = 0; // 因为从标准输入读取,回车键也会放入内核缓冲区,被上层读取。
    33.             std::cout << "echo# " << buffer << std::endl;
    34.         }
    35.         else if (n == 0)
    36.         {
    37.             std::cout << "end file" << std::endl;
    38.         }
    39.         else
    40.         {
    41.             // 区分是真正出错还是数据没有就绪这两种情况。
    42.             if (errno == EAGAIN || errno == EWOULDBLOCK)
    43.             {
    44.                 // 底层数据没有就绪,希望你下次继续来检测
    45.                 std::cout<<"data not ready"<
    46.                 continue;
    47.             }
    48.             else if (errno == EINTR)
    49.             {
    50.                 // 这次I/O被信号中断,也需要重新读取
    51.                 continue;
    52.             }
    53.             else
    54.             {
    55.                 //真正出错
    56.                 std::cout << "WARNING!!!  ERRNO: " << errno << ",error: " << strerror(errno) << std::endl;
    57.                 break;
    58.             }
    59.         }
    60.     }
    61.     return 0;
    62. }

  • 相关阅读:
    补环境框架
    Go 使用Viper处理Go应用程序的配置
    【超参数研究02】使用随机搜索优化超参数
    特斯拉Dojo超算:AI训练平台的自动驾驶与通用人工智能之关键
    免费申请Jetbrains全家桶
    集合~Map
    神奇代码备份恢复工具逸事与操作指南
    git服务器宕机后,怎么用本地仓库重新建立gitlab服务器(包括所有历史版本)
    减少Spring Boot的JVM内存占用的Docker三种配置
    【网络安全】处理应急响应的简单方法
  • 原文地址:https://blog.csdn.net/zzxz8/article/details/133460510