【问题标题】:Problem with "write" function in linuxlinux中“写”功能的问题
【发布时间】:2010-06-02 09:28:59
【问题描述】:

我正在尝试在 Linux 下编写 2 个服务器/客户端程序,它们通过命名管道进行通信。问题是,有时当我尝试从服务器写入不再存在的管道(客户端已停止)时,我收到“资源暂时不可用”错误并且服务器完全停止。

我知道这是由于在打开 fifo 通道时使用了 O_NONBLOCK 参数引起的,表明程序通常会等到它可以再次写入文件的时间点,但是有没有办法阻止这种行为,而不是如果出现问题,停止整个程序(写命令不应该返回 -1 并且程序正常继续)?

还有一个奇怪的地方是,这个错误只有在ide(eclipse)之外运行程序时才会出现。如果我在 Eclipse 中运行这两个程序,写入函数出错时只返回 -1 并且程序正常继续。

【问题讨论】:

    标签: c++ c linux concurrency


    【解决方案1】:

    如果您希望 write() 在出错时返回 -1(并将 errno 设置为 EPIPE),而不是在管道的写入端未连接时完全停止服务器,您必须忽略带有signal( SIGPIPE, SIG_IGN )SIGPIPE 信号。

    【讨论】:

      【解决方案2】:

      这种未定义行为的问题很奇怪,您可能在某个地方遇到了内存问题,或者您错过了测试。 (或者 Eclipse 做了一些特殊的事情来处理信号?)

      【讨论】:

      • 问题肯定出在write函数上。我在 write 调用之前和之后放置了 2 个“perror”......并且只显示第一个,因此程序存在于“write”函数调用中。我忘了提到当客户端关闭时,它也会从磁盘中删除文件,所以服务器的剩余文件描述符指向......什么都没有。
      • @Dumitru:没有任何代码来证明你在说什么,这个答案似乎是最好的选择,特别是考虑到你在问题中描述的所有行为。
      • 你应该用鸭嘴兽解决方案进行测试,但行为很奇怪
      【解决方案3】:

      引用第 2 节手册页进行写入: "[errno=]EPIPE 尝试写入管道或 FIFO,该管道或 FIFO 未打开以供任何进程读取,或仅打开一端(或写入由套接字(3SOCKET)创建的文件描述符,使用类型SOCK_STREAM 不再连接到对等端点)。还会向线程发送 SIGPIPE 信号。除非采取特殊措施来捕获或忽略信号,否则进程将终止。“[强调我的] .

      正如鸭嘴兽所说,您需要忽略 SIGPIPE 信号: signal(SIGPIPE, SIG_IGN)。您还可以在服务器中捕获信号并以不同的方式处理管道断开连接。

      【讨论】:

        【解决方案4】:

        也许你可以把它包装成一个“try..catch”语句?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-01-23
          • 2020-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-14
          • 2016-01-24
          相关资源
          最近更新 更多