posix pipe as message queue:阻塞写入+信号时会发生什么
posix pipe as message queue: What happens on blocked write + signal
我想使用管道作为内部消息队列,如下所述:posix pipe as a work queue
根据 glibc 的文档,如果数据小于 PIPE_BUF,则对管道的写入是原子的。
https://www.gnu.org/software/libc/manual/html_node/Pipe-Atomicity.html#Pipe-Atomicity
但是:如果出现信号,写入可能会被中断。假设 write
被阻塞是因为管道快满了。现在出现了一个信号。该数据会自动写入管道吗?
template <typename T>
ssize_t put(const T& data)
{
static_assert(sizeof(T) < PIPE_BUF, "We use the atomic property of the pipe write. So sizeof(T) MUST be smaller than PIPE_BUF");
int written;
const size_t id = T::value;
written = write(m_fds[write_fd], &id, sizeof(size_t));
assert(written == sizeof(size_t));
const size_t sT = sizeof(T);
write(m_fds[write_fd], &sT, sizeof(size_t));
assert(written == sizeof(size_t));
write(m_fds[write_fd], &data, sizeof(T)); // * this blocks in example
assert(written == sizeof(T));
return sizeof(T);
}
原子只是意味着 "the whole amount written in one operation is not interleaved with data from any other process."
信号中断略有不同。根据 the man page of signal,管道是 "slow device"。因此,除非设置了SA_RESTART
,否则write
操作将return 成功写入数据数。因此,最好经常检查write的return值,以确保所有数据都已写入。或者,您可以屏蔽可能的信号。
我想使用管道作为内部消息队列,如下所述:posix pipe as a work queue
根据 glibc 的文档,如果数据小于 PIPE_BUF,则对管道的写入是原子的。 https://www.gnu.org/software/libc/manual/html_node/Pipe-Atomicity.html#Pipe-Atomicity
但是:如果出现信号,写入可能会被中断。假设 write
被阻塞是因为管道快满了。现在出现了一个信号。该数据会自动写入管道吗?
template <typename T>
ssize_t put(const T& data)
{
static_assert(sizeof(T) < PIPE_BUF, "We use the atomic property of the pipe write. So sizeof(T) MUST be smaller than PIPE_BUF");
int written;
const size_t id = T::value;
written = write(m_fds[write_fd], &id, sizeof(size_t));
assert(written == sizeof(size_t));
const size_t sT = sizeof(T);
write(m_fds[write_fd], &sT, sizeof(size_t));
assert(written == sizeof(size_t));
write(m_fds[write_fd], &data, sizeof(T)); // * this blocks in example
assert(written == sizeof(T));
return sizeof(T);
}
原子只是意味着 "the whole amount written in one operation is not interleaved with data from any other process."
信号中断略有不同。根据 the man page of signal,管道是 "slow device"。因此,除非设置了SA_RESTART
,否则write
操作将return 成功写入数据数。因此,最好经常检查write的return值,以确保所有数据都已写入。或者,您可以屏蔽可能的信号。