C ++ - Sleep()和cin如何工作?

时间:2009-07-03 20:57:38

标签: c++ windows multithreading blocking scheduler

好奇。实际上Sleep()的工作原理是什么(在windows.h中声明)?也许不只是那个实现,而是任何人。我的意思是 - 它是如何实现的?如何使代码在特定时间内“停止”?同样好奇cin>>那些实际工作。他们到底做了什么?

我知道如何“阻止”继续运行的唯一方法是使用while循环,但考虑到与调用stdin方法时发生的情况相比,需要大量的处理能力(只是比较一段时间(真实)和stdin的读数),我猜这不是他们所做的。

7 个答案:

答案 0 :(得分:28)

操作系统使用一种称为调度程序的机制来保持它管理的所有线程或进程在一起运行良好。

每秒几次,计算机的硬件时钟中断CPU,导致操作系统的调度程序被激活。然后,调度程序将查看正在尝试运行的所有进程,并决定在下一个时间片中运行哪个进程。

它用来决定的不同事物取决于每个进程状态,以及它之前有多少时间。因此,如果当前进程一直在大量使用CPU,阻止其他进程取得进展,它将使当前进程等待并在另一个进程中进行交换,以便它可以完成一些工作。

但更常见的是,大多数进程都处于等待状态。例如,如果进程正在等待来自控制台的输入,则操作系统可以查看进程信息并查看其等待的io端口。它可以检查这些端口以查看它们是否有任何数据供该进程使用。如果他们这样做,它可以再次启动该过程,但如果没有数据,那么该过程将跳过当前时间片。

对于sleep(),任何进程都可以通知操作系统它想要等待一段时间。然后,即使在硬件中断之前,调度程序也会被激活(这也是当进程尝试从没有数据准备好被读取的流中执行阻塞读取时发生的情况),并且操作系统会记录该进程是什么等待。对于睡眠,该过程正在等待警报响起,或者每次重新启动时它可能再次产生,直到计时器启动。

由于操作系统仅在某些事情导致其抢占正在运行的进程(例如流程产生或我提到的硬件计时器中断)之后才恢复进程,sleep()不准确,具体取决于操作系统或硬件,但通常是一个或多个毫秒的量级。

如果需要更高的准确性或非常短的等待,唯一的选择是使用你提到的繁忙循环结构。

答案 1 :(得分:3)

操作系统安排进程如何运行(哪些进程有资格运行,按什么顺序运行......)。 Sleep()可能发出系统调用,告诉内核“不要让我使用处理器 x 毫秒”。

答案 2 :(得分:2)

简而言之,Sleep()告诉操作系统暂时忽略进程/线程。

答案 3 :(得分:1)

'cin'使用了大量的重载运算符。 '>>'通常是正确的位移,在C ++中几乎每种类型的右手操作数都会重载。为每个函数提供一个单独的函数,该函数从控制台读取并将输入转换为您给出的任何变量类型。例如:

std::cin::operator>> (int &rhs);

那不是真正的C ++ - 我暂时没有使用流和重载,所以我不记得返回类型或参数的确切顺序。不过,运行cin>>时会调用此函数。整数变量。

确切的底层实现取决于操作系统。

答案 4 :(得分:0)

答案取决于操作系统,但一般来说,操作系统要么安排一些其他代码在另一个线程中的其他位置运行,要么它确实无关,它会让CPU等到硬件事件发生,这会导致CPU跳转到一些称为中断处理程序的代码,然后可以决定运行什么代码。

答案 5 :(得分:0)

如果您正在寻找一种更受控制的方法来阻止多线程程序中的线程/进程,请查看信号量,互斥量,CriticalSections和事件。这些都是用于阻止进程或线程的技术(不通过while结构加载CPU)。

它们基本上是在等待/信号习惯用法中,其中被阻塞的线程正在等待,另一个进程发出信号告诉它再次启动。这些(至少在Windows中)也可以具有超时,从而提供与Sleep()类似的功能。

答案 6 :(得分:0)

在较低级别,系统有一个称为“调度程序”的例程,它将所有正在运行的程序的指令分派给实际运行它们的CPU。像“Sleep”和“usleep”这样的系统调用与告诉调度程序在一段固定时间内对该线程或进程进行IGNORE的指令匹配。

对于C ++流,“cin”隐藏了您正在访问的实际文件句柄(stdin和stdout实际上是这样的句柄),以及“>>” operator for it隐藏了读写的底层调用。由于它是一个接口,因此实现可以是特定于操作系统的,但从概念上讲,它仍然是像printf和scanf这样的东西。