【问题标题】:Reading all of a stuct or nothing from a pipe/socket in linux?从Linux中的管道/套接字读取所有结构或什么都没有?
【发布时间】:2016-02-18 15:05:44
【问题描述】:

我已经打开了一个子进程,它输出包含一些状态信息的固定大小的结构。我的计划是有一个单独的线程从该进程的标准输出中读取数据,以便在数据到来时提取数据。

我必须定期检查一个标志以确保程序仍在运行,以便我可以干净地关闭,所以我必须将管道设置为非阻塞,并且只需运行一个循环将状态消息拼接在一起.

有没有一种规范的方式可以告诉 Linux“在超时之前读取全部内容或不读取任何内容”,这样我就可以检查我的标志,但我不必处理读取的样板文件结构件餐?

或者,有没有办法将数据推回管道?我可以尝试阅读整个内容,如果它在一切准备好之前超时,请将我拥有的内容推回并稍后再试一次。

我还写了我的 popen(所以我可以获取标准输入和标准输出,所以如果有帮助的话,我完全可以使用套接字而不是管道)。

【问题讨论】:

  • 如果struct 小于PIPE_BUF,并且您在每次写入后刷新管道,I believe it should be atomic.
  • fread 负责这个
  • @ShadowRanger,struct 肯定比 PIPE_BUF 小,但我不能保证它全部写在一个调用中,所以我认为这破坏了原子性。
  • 您是否看到了由非阻塞管道引起的实际错误,或者这更像是一个关于竞争条件可能性的理论问题?
  • @Matt 不,它现在工作正常,如果我有我正在考虑的 read_all_or_nothing 语义,代码会更干净。

标签: c++ linux sockets pipe posix


【解决方案1】:

这就是我最终为任何好奇的人所做的事情。我刚刚编写了一个包含文件描述符和消息大小的类,并为我提供了我想要的“全有或全无”行为。

struct aonreader { 
    aonreader(int fd, ssize_t size) { 
        fd_      = fd;
        size_    = size_;
        nread_   = 0;
        nremain_ = size_;
    }

    ssize_t read(void *dst) { 
         ssize_t ngot = read(fd, (char*)dst + nread_, nremain_);
         if (ngot < 0) { 
             if (errno != EAGAIN && errno != EWOULDBLOCK) {
                  return -1; // error
             }
         } else {
             nread_   += ngot;
             nremain_ -= ngot;

             // if we read a whole struct
             if (nremain_ == 0) {
                 nread_   = 0;
                 nremain_ = size_;
                 return size_;
             }
         }
         return 0;             

    private:
         int     fd_;
         ssize_t size_;
         ssize_t nread_;
         ssize_t nremain_;
    };

然后可以这样使用:

    thing_you_want thing;
    aonreader buffer(fd, sizeof(thing_you_want));
    while (running) { 
        size_t ngot = buffer.read(&thing);
        if (ngot == sizeof(thing_you_want)) { 
            <handle thing>
        } else if (ngot < 0) { 
            <error, handle errno>
        }
        <otherwise loop and check running flag>
    }

【讨论】:

    猜你喜欢
    • 2018-10-28
    • 2013-09-05
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多