【发布时间】:2020-10-28 01:21:14
【问题描述】:
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
int main(){
// Make stdin non-blocking
fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
printf("stdout O_NONBLOCK is: %d\n", fcntl(STDOUT_FILENO, F_GETFL) & O_NONBLOCK);
printf("stdin O_NONBLOCK is: %d\n", fcntl(STDIN_FILENO , F_GETFL) & O_NONBLOCK);
for(int i=0; i<16; i++){
cout<<" "<<"fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er "<<endl;
}
bool cerrfail=cerr.fail(), coutfail=cout.fail();
flush(cout); flush(clog); flush(cerr);
cout.clear(); cerr.clear(); clog.clear();
cerr<<"\ncerr.fail():"<<cerrfail<<" cout.fail():"<<coutfail<<endl;
}
可能的输出:
编译器 G++ 9.3
MacOS Mojave 10.14.6
stdout O_NONBLOCK is: 4
stdin O_NONBLOCK is: 4
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo erouhep hv reough er
fgvbhln;j;jblhcbwnoi wiejnocje ocweo cewoj coj weoj cowejojewohewouspuweoche njwpihbeh wjo ero
cerr.fail():0 cout.fail():1
因为fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);而失败
为什么?如何解决保持标准输入非阻塞的问题?
更新。 为什么?因为设置 stdin O_NONBLOCK 也会使 stdout O_NONBLOCK。并且 std::out 在其内部接收到一些 ASYNC 错误代码(如 ETRYAGAIN)。
我看到了两种解决方案:
- 使 std::cout 不会因 O_NONBLOCK 而失败
- 让标准输入 O_NONBLOCK 保持标准输出阻塞?
更新2。 该问题仅出现在 MacOS 上。不在 Linux amd64 上,也不在 Linux MIPS (Atheros) 上。
【问题讨论】:
-
您的通话后标准输出是否也是非阻塞的? stackoverflow.com/q/23865898/1133144
-
是的。它将非阻塞设置为
stdout O_NONBLOCK is: 4 stdin O_NONBLOCK is: 4 -
您使用的是什么编译器、版本、编译器选项?你在哪个平台?您使用的是什么 C 和 C++ 标准库的实现?我认为,如果这是特定于 OSX 的,请考虑使用 OSX 对其进行标记。我无法使用 glibc 在 linux 上重现,(在 linux
O_NONBLOCK = 2048上)。 -
@KamilCuk,感谢您的回复,我添加了有关我的系统的详细信息。
-
您的更新并没有真正解释为什么您希望
stdout是非阻塞的。这样做有什么好处?如果尝试输出会生成错误代码,那么听起来您遇到了 X-Y 问题,应该改正 that。
标签: c++ stdout iostream nonblocking fcntl