gpt4 book ai didi

c++ - 从原子内容的意义上说,从匿名管道中读取是原子的吗?

转载 作者:太空狗 更新时间:2023-10-29 20:23:35 25 4
gpt4 key购买 nike

我正在用两个线程在 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 than nbyte. The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte, if the read() request was interrupted by a signal, or if the file is a pipe or FIFO or special file and has fewer than nbyte bytes immediately available for reading. For example, a read() from a file associated with a terminal may return one typed line of data.

因此,write()会写原子单位; read()只会读取原子单位,因为那是写的。不会有问题的,我一开始就说了。

关于c++ - 从原子内容的意义上说,从匿名管道中读取是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32417843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com