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