Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在linux中,从管道/套接字读取所有stuct还是什么都不读取?_C++_Linux_Sockets_Pipe_Posix - Fatal编程技术网

C++ 在linux中,从管道/套接字读取所有stuct还是什么都不读取?

C++ 在linux中,从管道/套接字读取所有stuct还是什么都不读取?,c++,linux,sockets,pipe,posix,C++,Linux,Sockets,Pipe,Posix,我有一个子进程,它输出包含一些状态信息的固定大小的结构。我的计划是有一个单独的线程,从该进程的stdout读取数据 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)) {

我有一个子进程,它输出包含一些状态信息的固定大小的结构。我的计划是有一个单独的线程,从该进程的stdout读取数据

    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>
    }
我必须定期检查一个标志,以确保程序仍在运行,这样我就可以干净地关闭,所以我必须将管道设置为非阻塞,只需运行一个将状态消息拼接在一起的循环

    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>
    }
有没有一种规范的方法可以告诉Linux“要么在超时之前读取全部内容,要么什么都不读”,这样我就可以检查我的标记,但我不必处理读取结构片段的样板文件

    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>
    }
或者,有没有办法将数据推回到管道中?我可以试着阅读整件事,如果它在准备好之前就超时了,把我的东西放回去,过一会儿再试一次

    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>
    }

我还写了我的popen(这样我就可以抓取stdin和stdout,所以如果有帮助的话,我完全可以使用套接字而不是管道)。

下面是我最后为好奇的人做的事情。我刚刚编写了一个类,它包装了文件描述符和消息大小,并提供了我想要的“全部或无”行为

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>
    }
struct aonreader{
aonreader(intfd,ssize_t size){
fd=fd;
大小=大小;
nread=0;
nremain=尺寸;
}
ssize_t read(void*dst){
ssize_t ngot=读取(fd,(char*)dst+nread_uu,nremain_uu);
如果(ngot<0){
if(errno!=EAGAIN&&errno!=ewoldblock){
返回-1;//错误
}
}否则{
nread_uuz+=ngot;
nremain_u-=ngot;
//如果我们读一个完整的结构
如果(nremain_u==0){
nread=0;
nremain=尺寸;
返回大小;
}
}
返回0;
私人:
int fd_;
大小;
重新阅读;
谢谢你;
};
然后可以这样使用:

    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>
    }
你想要的东西;
aonreader缓冲区(fd,sizeof(您想要的东西));
当(运行时){
size\u t ngot=buffer.read(&thing);
如果(ngot==sizeof(你想要的东西)){
}else如果(ngot<0){
}
}

如果
结构
小于
管道_BUF
,并且您在每次写入后冲洗管道,
fread
负责this@ShadowRanger,这个结构肯定比PIPE_BUF小,但我不能保证它都是在一个调用中编写的,所以我认为这打破了原子性。你看到了实际的错误吗e是由非阻塞管道引起的,还是这更像是一个关于竞争条件可能性的理论问题?@Matt no它现在运行良好,如果我有我正在考虑的read_all_或_nothing语义,代码就会更干净。