2017-02-28 146 views
1

从这个post这听起来像fgets()意味着是一个阻塞调用,但是,this手册页显示,如果设置为非阻塞,它将返回NULLerrnoEWOULDBLOCK如果没有数据已准备好被读取,因此我的假设是,确实有可能将它用作非阻塞。在f中使用fgets()作为非阻塞调用是否安全?

我知道select()和朋友,我只想知道它是否安全地使用它作为非阻塞?如果不是,这些原因是什么?

+0

定义“安全”。如果你正确使用它,那么是“安全”的。 – kaylum

+0

正常使用。它听起来好像是不正确的使用它作为非阻塞,但如果它是,那么我想这回答了这个问题。谢谢 – user1024718

+0

如果底层fd是普通文件(不是pipe,tty,fifo或socket),即使将它设置为非阻塞,读仍将在Linux上阻塞。 – PSkocik

回答

0

我想知道是否可以安全地使用它作为非阻塞?如果不是,那是什么原因?

这取决于你的意思是“安全”。 C本身没有非阻塞I/O的概念,所以如果你编写的代码必须是可移植的,那么即使假设非阻塞I/O是可用的替代方案也是不安全的。

如果您正在编写更具体的环境,例如POSIX环境,那么您可能可以依赖非阻塞I/O的可用性,但应该考虑确定该环境的规范以确定当您指定的文件在某些​​相关意义上处于非阻塞模式时,您可能会从fgets()期望什么行为。 POSIX并指定fgets()应的误差在相同条件下不能在该fgetc()确实,其中之一是

O_NONBLOCK标志被设置为文件描述符基本流和所述线程将在[fgets()被延迟]操作。

有了这样的情况下,如果你定义为“POSIX指定”,然后是“安全”,依靠fgets()不阻止当底层底层打开文件的描述在非阻塞模式是安全的。

@R ..在评论中断言,在处于非阻塞模式的文件上使用stdio函数可能会导致数据丢失。这很合理,但我还没有找到这个说法的依据。我不打算在这一点上与他矛盾,但是,再一次地,你提出的建议是否“安全”取决于你的意思。

+0

POSIX确实指定。 'EAGAIN'是'fgetc'的强制性错误(根据其定义的'fgets'),错误时,'ferror'指示器被设置,并且缓冲区和文件位置的状态未被指定。因此,您**将获得数据丢失**尝试在非阻塞模式下使用stdio。 –

+0

@R ..,你是对的。也就是说,'fgets()'的文档是指错误条件下的'fgetc()',这是我忽略的。它是* general *行为不是用'fgetc()'来定义的。我会暂时更新我的​​答案。 –

+0

@R ..对不起,您对您的意思是什么会导致数据丢失?这是否意味着在某些实现中它会起作用,而有些您在下次可用读取时不会获得您期望的数据? – user1024718