- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在用两个线程在 Linux 上编写一个进程。它们使用通过 pipe()
调用创建的匿名管道进行通信。
一端是将 C 结构复制到管道中:
struct EventStruct e;
[...]
ssize_t n = write(pipefd[1], &e, sizeof(e));
另一端从管道中读取:
struct EventStruct e;
ssize_t n = read(pipefd[0], &e, sizeof(e));
if(n != -1 && n != 0 && n < sizeof(e))
{
// Is a partial read possible here??
}
匿名管道可以进行部分读取吗?
手册页 (man 7 pipe
) 规定任何低于 PIPE_BUF 大小的写入都是原子的。但他们的意思是关于其他作者线程的原子性......我不关心多个作者问题。我只有一个作者线程,也只有一个读者线程。
附带说明一下,我的结构有 56 个字节长。远低于 PIPE_BUF 大小,在 Linux 上至少为 4096 字节。看起来它在最新的内核上更高。
否则说明:在读取端,我是否必须在接收完整结构实例的同时处理部分读取并存储它们?
最佳答案
只要您处理的是固定大小的单位,就没有问题。如果您在管道上写入一个 N 字节的单元,并且读取器从管道请求一个 N 字节的单元,那么就不会有问题。如果您不能一口气读取所有数据(例如,在读取数据长度之前您不知道其大小),那么生活就会变得更加棘手。但是,如图所示,您应该没问题。
也就是说,您仍然应该检测短读。如果您阅读的内容很短,但假设它是全长的,那将是一场灾难。但是,您不应该期望检测到短读取——代码覆盖率将是一个问题。我只是测试 n < (ssize_t)sizeof(e)
并且检测到的任何内容都是错误或 EOF。注意类型转换;否则,有符号值将被转换为无符号和 -1
不会被正确发现。
对于规范,您需要阅读以下 POSIX 规范:
并可能跟踪来自这些页面的链接。例如,对于 write()
,规范说:
Write requests to a pipe or FIFO shall be handled in the same way as a regular file with the following exceptions:
There is no file offset associated with a pipe, hence each write request shall append to the end of the pipe.
Write requests of {PIPE_BUF} bytes or less shall not be interleaved with data from other processes doing writes on the same pipe. Writes of greater than {PIPE_BUF} bytes may have data interleaved, on arbitrary boundaries, with writes by other processes, whether or not the O_NONBLOCK flag of the file status flags is set.
或来自read()
的规范:
Upon successful completion, where
nbyte
is greater than 0,read()
shall mark for update the last data access timestamp of the file, and shall return the number of bytes read. This number shall never be greater thannbyte
. The value returned may be less thannbyte
if the number of bytes left in the file is less thannbyte
, if the read() request was interrupted by a signal, or if the file is a pipe or FIFO or special file and has fewer thannbyte
bytes immediately available for reading. For example, aread()
from a file associated with a terminal may return one typed line of data.
因此,write()
会写原子单位; read()
只会读取原子单位,因为那是写的。不会有问题的,我一开始就说了。
关于c++ - 从原子内容的意义上说,从匿名管道中读取是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32417843/
有没有办法用连词创建原子 if ?也就是说,我可以以某种方式在 C 中自动测试 if(A && B) 吗?如果它在第一个连接处短路,那么没问题,但如果没有短路,则在检查 B 时,A 可能已更改。有什么
我有很多 fork 的过程。子进程做很多事情和另一个系统调用。 当任何子进程从系统调用中获取错误时,它会将错误描述打印到 stderr 并将 SIGUSR1 发送到组长(主要父进程)。 SIGUSR1
阅读 boost::atomic 上的文档和 std::atomic 让我感到困惑的是 atomic 是否接口(interface)应该支持非平凡类型? 也就是说,给定一个只能通过将读/写包含在一个完
我有一个命令,可以将叠加图像放在视频上。 之后,我调整输出大小以适合某些尺寸。 通常一切正常,但有时且仅在某台台式计算机上,当第二次精化开始时,命令返回错误:moov atom not found 让
我最近发现当 LANG 设置为 C.utf8 时,X11 原子 WM_NAME 未在 Swing JFrame 中设置。但为 LANG 的其他值设置。这发生在带有 OpenJDK 11.0.9 的 L
我目前正在使用blackmagic的prorecorder录制视频。我使用 ffmpeg 将视频即时转码为 mp4 视频容器。持续时间未知,因为我正在对 prorecorder 输出到命名管道的 .t
这里真的有人使用 atom 来处理 git 提交消息吗?我想但我遇到了这个问题并且一直坚持使用 git commit -m '....' 。当我尝试使用 atom 时,它会打开 atom,我几乎立即从
考虑: void foo() { std::vector> foo(10); ... } foo 的内容现在有效吗?或者我是否需要显式循环并初始化它们?我检查过 Godbolt,看起来不错,但
在official FAQ我阅读的 Memcached: “发送到 memcached 的所有单独命令都是绝对原子的。” 然而,当涉及到 get_multi 和 set_multi 时,我仍然不清楚。
在测试程序的可扩展性时,我遇到了必须将 memcpy 操作设置为原子操作的情况。我必须将 64 字节的数据从一个位置复制到另一个位置。 我遇到了一种解决方案,即使用旋转变量: struct recor
我对 C++ 原子变量感到困惑。如果我有一个原子 x,我想在一个线程中递增并在另一个线程中读取,我可以执行++x 还是必须执行 x.atomic_fetch_add(1)。在读者线程中,我可以做类似
跟进自 Multiple assignment in one line ,我很想知道这对原子数据类型是如何工作的,特别是 bool 类型的例子。 给定: class foo { std::at
我想创建一个版本控制系统,并且对版本号为 1 的新条目的查询如下所示: ID 和修订号组合起来就是主键。 insert into contentfile (id, name, revision, ac
我在 iOS 项目中有下一个独立的测试片段: /// ... std::atomic_bool ab; ab.store(true); bool expected = false; while (!a
我了解如何使用条件变量(此构造的名称很糟糕,IMO,因为 cv 对象既不是变量也不表示条件)。所以我有一对线程,canonically使用 Boost.Thread 设置为: bool awake =
因此,对于最终项目,我尝试制作一款包含三种不同 meteor 的游戏;铜牌、银牌和金牌。虽然青铜阵列在Setup()中工作正常,但银色和金色 meteor 由于某种未知原因而高速移动。 functio
第一个问题,为什么不在 atomic_compare_exchange_weak 操作的参数中应用后缀求值 (++)?运算前后a的值相同。然而,当在 printf() 中使用时,正如预期的那样,该值会
我正在尝试使用 OpenMP 对已经矢量化的代码进行内部函数并行化,但问题是我使用一个 XMM 寄存器作为外部“变量”,我会在每个循环中递增。现在我正在使用 shared 子句 __m128d xmm
clojure“atom”的文档指出 - "Changes to atoms are always free of race conditions." 但是,竞争条件不仅根据更改定义,而且在不同线程中
我一直在研究原子引用计数的实现。 库之间的大多数操作都非常一致,但我在“减少引用计数”操作中发现了惊人的多样性。 (请注意,通常情况下,shared 和 weak decref 之间的唯一区别是调用了
我是一名优秀的程序员,十分优秀!