如何`while(1)`优化不占用所有资源?

Der*_*unk 1 c linux loops scheduling

假设我有一些代码执行此操作:

while(1) {
      scanf("%c", &key);
      // if E or e, exit
      if (key == 'E' ||  key == 'e')
          break;
}
Run Code Online (Sandbox Code Playgroud)

这显然不会占用甚至单个核心的所有资源.它只是......"坐在那里",直到有人真正按下E.我的问题是:运行时如何发现它不应占用核心的所有资源等待scanf?scanf是一个特殊情况,因为它是I/O,因此操作系统安排它直到有效按下一个键?我可以以某种方式强迫它一直在while说,a++在循环中添加一个内部吗?

cni*_*tar 6

scanf是一种特殊情况,因为它是I/O,因此操作系统会安排它直到有效按下一个键

这正是发生的事情.在这种情况下scanf阻塞操作.也就是说,如果它不能立即执行(输入缓冲区中没有任何内容),操作系统只会让您的进程进入睡眠状态,记住在某些事情发生时将其唤醒.

我可以通过在循环中添加一个++来强制它一直在进行

一个a++不会改变任何东西.只要您有长时间等待的阻止呼叫,您将无法挂住CPU.


直到有效按下一个键

在Linux中输入通常是"熟".也就是说,按一个键通常不够(在进程有机会查看数据之前,您还需要点击返回).


正如Basile在评论中正确提到的scanf可能并不总是阻止.如果stdio缓冲区中有足够的输入,则只scanf返回它.如果不是,那么它将调用read(2)哪个可以阻止.

  • 实际上(至少在Linux上),`scanf`将调用一个阻塞操作(`read(2)`syscall).`scanf`并不总是阻塞(如果`stdin`文件缓冲区有字节,它可以使用它们)但它可能会调用一个阻塞原语(Posix系统上的`read(2)`).在Windows上,你有相同的东西. (2认同)