write()系统调用什么时候写入所有请求的缓冲区而不仅仅是部分写入?

如果我在write()系统调用中写入例如100字节,我总是把这个write()调用放在一个循环中,检查返回的长度是否是我期望发送的长度,如果不是,它碰撞缓冲区指针并减less写入量的长度。

所以我再一次做到了这一点,但现在有了StackOverflow,我可以问你们,如果有人知道我写的东西什么时候会写出我要求的所有东西,还给我一个部分写入?

附加注释:X-Istence的回复提醒我,我应该注意到文件描述符是阻塞的(即不是非阻塞的)。 我认为他暗示,一个阻塞文件描述符上的write()不会写入所有指定的数据的唯一方法是当write()被一个信号中断时。 这似乎至less让我觉得直觉…

Solutions Collecting From Web of "write()系统调用什么时候写入所有请求的缓冲区而不仅仅是部分写入?"

你需要检查errno来查看你的调用是否被中断,为什么write()返回的时间早,为什么只写了一定数量的字节。

从男人2写

当在诸如需要流控制的套接字的对象上使用非阻塞I / O时,write()和writev()可能会写入比请求更少的字节; 必须注意返回值,并在可能的情况下重试其余的操作。

基本上,除非你正在写一个非阻塞的套接字,否则唯一会发生的是如果你被一个信号中断。

[EINTR]信号在完成之前中断了写入。

请参阅手册页中的“错误”部分,以获取有关可返回内容以及返回时间的更多信息。 从那里你需要弄清楚错误是否严重到足以记录错误并退出,或者你是否可以继续操作!

这一切都在Marc J. Rochkind的“ 高级Unix编程 ”一书中讨论过,我在本书的帮助下编写了无数的程序,并且会在为像UNIX这样的UNIX进行编程时提出建议。

写入可能会返回部分写入,特别是使用套接字上的操作或内部缓冲区已满。 所以好办法是做以下事情:

 while(size > 0 && (res=write(fd,buff,size))!=size) { if(res<0 && errno==EINTR) continue; if(res < 0) { // real error processing break; } size-=res; buf+=res; } 

永远不要继续通常发生的事情…

注意:如果磁盘满了,您将得到ENOSPC不能部分写入。

写入应该没有任何理由写一个部分缓冲区afaik。 我可以考虑的一个部分写入的原因是,如果磁盘空间不足,你正在写一个块设备的末尾,或者如果你正在写一个字符设备/其他类型的设备。

但是,盲目重试的计划可能不是一件好事 – 检查errno是否应该先重试。