根据手册页,写入命令“写入计数字节”,然后返回实际写入的字节数。因此,如果我想确保所有字节都写入文件描述符,我需要将写入放入循环中并监视所有字节是否已写入。
但是,有没有一种方法可以配置文件描述符,以便写入块直到全部字节已被写入?
编辑*如果这有什么区别的话,我正在写信给管道。
答案1
您只提到了系统调用,所以我假设您只想通过系统调用接口将所有数据传递到操作系统,仅此而已。
因此,如果我想确保所有字节都写入文件描述符,我需要将写入放入循环中并监视所有字节是否已写入。
是的。
尽管据我(在 Linux 上)测试,实际上大多数写入都会阻塞,直到所有内容都写入为止。这至少包括写入常规文件和(据我记得)管道。当然,如果您将文件描述符设置为非阻塞模式,则可能不会发生这种情况(不确定它是否适用于常规文件),并且您可能会在系统调用中间收到一个信号,从而中断它。这里的确切行为可能取决于系统。
但是,是否有一种方法可以配置文件描述符,以便写入块直到所有字节都被写入?
不。
如果系统调用被信号中断,并且控制权传回给您的程序,它甚至可能不想继续。因此,由应用程序决定是否继续。
答案2
您有两个选择:
使用带 O_SYNC 标志的 open。来自联机帮助页:
O_SYNC Write operations on the file will complete according to the re‐
quirements of synchronized I/O file integrity completion (by
contrast with the synchronized I/O data integrity completion
provided by O_DSYNC.)
By the time write(2) (or similar) returns, the output data and
associated file metadata have been transferred to the underlying
hardware (i.e., as though each write(2) was followed by a call
to fsync(2)). See NOTES below.
或者在 write 调用之后使用 fsync(2) 调用,这将显式刷新数据。
根据您的性能和保证需求,您可能更喜欢其中一种方式。
由于你的问题是关于管道的,所以没有必要。所有写入都会进入管道并被视为已写入,除非出现错误(例如非阻塞模式下管道已满),不需要同步/直接或任何标志或特殊调用。如果您正在谈论延迟从写入返回直到管道读取器读取数据,那么您应该仔细检查要求。可以制作一个具有有限缓冲区的管道,以便写入始终会阻塞,直到读取器访问它为止,但为什么要费力设计和测试这样的场景呢?如果您确实需要读者的反馈,那么也许您应该明确地获取反馈。读者总是可能在调用管道上的读取后立即死亡,因此阻塞管道来创建方案似乎毫无价值。