有没有办法强制写入命令阻塞,直到所有字节都被写入?

有没有办法强制写入命令阻塞,直到所有字节都被写入?

根据手册页,写入命令“写入计数字节”,然后返回实际写入的字节数。因此,如果我想确保所有字节都写入文件描述符,我需要将写入放入循环中并监视所有字节是否已写入。

但是,有没有一种方法可以配置文件描述符,以便写入块直到全部字节已被写入?

编辑*如果这有什么区别的话,我正在写信给管道。

答案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) 调用,这将显式刷新数据。

根据您的性能和保证需求,您可能更喜欢其中一种方式。

由于你的问题是关于管道的,所以没有必要。所有写入都会进入管道并被视为已写入,除非出现错误(例如非阻塞模式下管道已满),不需要同步/直接或任何标志或特殊调用。如果您正在谈论延迟从写入返回直到管道读取器读取数据,那么您应该仔细检查要求。可以制作一个具有有限缓冲区的管道,以便写入始终会阻塞,直到读取器访问它为止,但为什么要费力设计和测试这样的场景呢?如果您确实需要读者的反馈,那么也许您应该明确地获取反馈。读者总是可能在调用管道上的读取后立即死亡,因此阻塞管道来创建方案似乎毫无价值。

相关内容