select(2)保证多少数据量能够无阻塞地写入文件

问题描述 投票:0回答:4

select
(2)(除其他外)告诉我是否可以在不阻塞的情况下写入文件的 fd。但是,它能保证我可以无阻塞地写入完整的 4096 字节吗?

注意 我对磁盘上的普通文件感兴趣。不是插座之类的。

换句话说:当我们可以在不阻塞的情况下将一个字节写入文件 fd 时

select
是否发出信号,当我们可以向文件写入 n (4096, ... ?) 个字节时 or 是否发出信号fd 无阻塞。

c linux posix-select
4个回答
3
投票

每当

select()
指示您的文件已准备好时,您可以尝试写入N个字节,对于任何N>0。
write()
将返回实际写入的字节数。如果等于N,就可以再写一次。如果小于N,则下一次写入将被阻塞。

注意 磁盘上的普通文件不会阻塞。插座、管道和端子都可以。


3
投票

您给这个标记了“Linux”,那么内核源代码告诉您什么?阅读系统调用实现来查找 select 何时决定将文件描述符视为准备写入应该很容易。

但是,如果您担心阻塞,那么您就做错了。如果您不想阻止,请使用

O_NONBLOCK
或等效项。即使
select
确实保证可以在不阻塞的情况下写入一定数量的字节,这也仅在
select
返回时成立;当您实际执行写入时,它可能不一定是真的。


3
投票

注意我对磁盘上的普通文件感兴趣。不是插座之类的。

select 不适用于普通文件,仅适用于套接字/管道/tty 以及可能的其他文件,但不适用于常规文件。对于常规文件, select 始终将文件描述符表示为可读/可写 - 因此,将 select 与文件一起使用是一项相当无用的练习。

请注意,这也适用于其他 io 多路复用设施,例如 poll/epoll。 AIO 将对常规文件进行异步 io,但操作系统支持可能会有所不同,而且它是一个相当复杂的 api 使用起来

至于可以写入多少数据,没有承诺。 4096 并不是一个神奇的数字,当应用于使用 select 确实有意义的文件描述符(套接字/管道/等)时, select 假设您可以无阻塞地写入。因为您无法知道在不阻塞的情况下可以写入多少数据,所以您应该始终将文件描述符设置为非阻塞,记录实际写入的数据量(如 write/send 的返回值所示),并从该点开始写入下次选择表示可以再次写入数据。


1
投票

select() 仅承诺可以在不阻塞的情况下进行适用的调用,它不保证您的情况下的 I/O 量 (4096)。由于 select() 可以与不同类型的描述符(文件、套接字、串行连接等)一起使用,您可能会注意到,对于磁盘操作,观察到的行为是始终可以写入完整的缓冲区,但这又是特定于特定的底层操作而不是 select() 的承诺。

© www.soinside.com 2019 - 2024. All rights reserved.