检查 fgets 是否会阻塞

发布于 2024-08-30 21:59:08 字数 458 浏览 5 评论 0原文

我只是想知道在 C 中是否可以查看输入缓冲区或执行类似的技巧来了解对 fgets 的调用是否会在稍后阻塞。 Java 允许通过调用 BufferedReader.ready() 来执行类似的操作,这样我就可以实现类似这样的控制台输入:

while (on && in.ready()) { 
  line = in.readLine();
  /* do something with line */
  if (!in.ready())
    Thread.sleep(100);
}

这允许外部线程通过设置为 false 来正常关闭输入循环;我想在 C 中执行类似的实现,而不诉诸不可移植的技巧,我已经知道我可以通过诉诸信号或(更好,即使需要处理缓冲)重新实现在 unix 下创建“超时 fgets”它位于 recv/select 之上,但我更喜欢也能在 Windows 上运行的东西。

TIA

I was just wondering whether in C is it possible to peek in the input buffer or perform similar trickery to know whether a call to fgets would block at a later time.
Java allows to do something like that by calling BufferedReader.ready(), this way I can implement console input something like this:

while (on && in.ready()) { 
  line = in.readLine();
  /* do something with line */
  if (!in.ready())
    Thread.sleep(100);
}

this allows an external thread to gracefully shutdown the input loop by setting on to false; I'd like to perform a similar implementation in C without resorting to non portable tricks, I already know I can make a "timed out fgets" under unix by resorting to signals or (better, even though requering to take care of buffering) reimplement it on top of recv/select, but I'd prefer something that would work on windows too.

TIA

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

箜明 2024-09-06 21:59:08

建议使用套接字 I/O 例程,最好使用需要毫秒的 poll() 作为超时,最终您可以将超时(返回值 = -1 )解释为输入缓冲区中的数据不可用。
在我看来,没有非阻塞标准I/O函数来实现这个功能。

Suggest to go with socket I/O routines,preferably poll() with required millisecond as timeout and eventually you can interpret timeout ( return value = -1 ) as unavailability of data in input buffer.
In my opinion,there is no non-blocking standard I/O function to achieve this functionality.

灼痛 2024-09-06 21:59:08

我不确定你在说什么:套接字还是文件句柄?

对于文件来说不应该有阻塞。该函数立即返回(除了 I/O 调用本身)。

对于套接字 - 您可以使用ioctlsocket函数:
以下内容告知是否有待处理的 rcv 数据:

ULONG nSize;
ioctlsocket(sock, FIONREAD, &nSize);

以下内容将套接字转换为非阻塞模式:

ULONG nEnable = 1;
ioctlsocket(sock, FIONBIO, &nEnable);

当处于非阻塞模式时 - 套接字上的函数永远不会阻塞。如果它们无法满足请求,则会返回错误,错误代码为 WSAEWOULDBLOCK

另外,在 Windows 上有许多更有效的方法。它们是:

  • 使用重叠 I/O。这很重要,但提供了
  • 将套接字与可等待事件关联的卓越性能。这会将套接字转换为非阻塞模式,并且当网络事件发生时会发出指定事件的信号。
  • 将其与窗口句柄关联。这对于面向 UI 的程序来说很方便。

I'm not certain what are you talking about: a socket or a file handle?

For files there should be no blocking. The function returns immediately (besides of the I/O invocation itself).

For sockets - you may use the ioctlsocket function:
The following tells if there's a rcv data pending:

ULONG nSize;
ioctlsocket(sock, FIONREAD, &nSize);

The following transfers the socket into non-blocking mode:

ULONG nEnable = 1;
ioctlsocket(sock, FIONBIO, &nEnable);

When in Non-blocking mode - functions on socket never block. If they can't fulfill the request they return an error, and the error code is WSAEWOULDBLOCK

Plus, on Windows there're dozens of much more efficient methods. Those are:

  • Using Overlapped I/O. This is non-trivial, but gives superior performance
  • Associating socket with a waitable event. This transfers the socket to a non-blocking mode, plus the specified event is signaled when a network event occurs.
  • Associate it with the window handle. This is convenient for UI-oriented programs.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文