从 Linux 中的管道/套接字读取所有结构或什么都没有
Reading all of a stuct or nothing from a pipe/socket in linux?
我有一个子
进程,我打开了它输出包含一些状态信息的固定大小的结构。 我的计划是有一个单独的线程,从该过程的 stdout 读取数据,以便在数据到来时提取数据。
我必须定期检查一个标志以确保程序仍在运行,以便我可以干净地关闭,所以我必须将管道设置为非阻塞,并且只需要运行一个将状态消息拼凑在一起的循环。
有没有一种规范的方法可以告诉 Linux"要么在超时之前读取全部内容,要么什么都不读取",这样我就可以检查我的标志,但我不必处理阅读结构零碎的样板?
或者,有没有办法将数据推送回管道? 我可以尝试阅读整个内容,如果它在一切准备就绪之前超时,请将我所拥有的内容推回去,然后再试一次。
我还编写了我的 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>
}
相关文章:
- 有什么方法可以遍历结构吗
- 在 c++ 中拥有一组结构的正确方法是什么?
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- C++中deque数据结构的大O是什么?
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 将信息输入到下面显示的结构向量中的正确语法/格式是什么
- 不同的类或结构初始化方法之间的性能差异是什么?
- 结构块指的是什么?
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- C++ 类层次结构中的"对齐"是什么意思?
- 自定义数据结构的优点是什么?
- 如果结构中的字符串比使用的 p/调用签名长或短,会发生什么情况?
- 我的堆栈和库存清单程序的结构有什么问题?
- 将此私有删除器函数包装在结构中的目的是什么?
- 在只读(即 const)访问器上执行结构化绑定的最佳实践是什么?
- 清除结构向量时会发生什么?
- 这里的以下 OOP 结构是什么?
- 用于筛子的最佳数据结构是什么(即一些被划掉的数字列表)?
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 当C++类函数参数之一是结构时,它们的语法有什么不同