只是好奇。 Sleep()函数实际上是如何工作的(在windows.h中声明的)? 也许不仅仅是这个实现,而是任何人。 我的意思是 – 它是如何实现的? 如何使代码在特定时间“停止”? 也好奇cin >>和那些实际上工作 。 他们究竟做了什么?
我知道如何“阻止”继续运行的唯一方法是使用while循环,但是考虑到这与处理从stdin读取方法时发生的情况相比,需要大量的处理能力(只是比较一段时间(真正)从标准input读取),我猜这不是他们做的。
操作系统使用称为调度程序的机制来保持它所管理的所有线程或进程很好地一起工作。
计算机的硬件时钟每秒数次中断CPU,导致操作系统的调度程序被激活。 然后,调度程序将查看所有正在尝试运行的进程,并决定哪个进程在下一个时间片运行。
它用来决定的不同的东西取决于每个进程状态,以及它以前有多少时间。 因此,如果当前进程大量使用CPU,阻止其他进程进行,则会使当前进程在另一个进程中等待并交换,以便可以进行一些工作。
然而,更多的时候,大多数流程将处于等待状态。 例如,如果进程正在等待来自控制台的输入,则操作系统可以查看进程信息并查看其等待的端口。 它可以检查这些端口是否有任何数据供进程使用。 如果他们这样做,它可以重新启动进程,但是如果没有数据,那么当前时间片跳过该进程。
至于sleep()
,任何进程可以通知操作系统,它想等待一段时间。 即使在硬件中断之前,调度程序也会被激活(当进程试图从没有数据准备好被读取的流中进行阻塞读操作时,也会发生这种情况),操作系统会记录过程是什么等待。 对于睡眠,该过程正在等待警报消失,或者每次重新启动时都会再次产生,直到定时器启动。
由于操作系统只是在某些事件导致它抢占正在运行的进程(例如进程产生或硬件计时器中断sleep()
之后才恢复进程,所以sleep()
不是很准确,准确度取决于操作系统或硬件,但通常是一个或多个毫秒的顺序。
如果需要更多的准确性或者很短的等待时间,唯一的选择就是使用你提到的busy loop结构。
操作系统安排进程如何运行(哪些进程有资格运行,按什么顺序,…)。 Sleep()
可能会发出一个系统调用,告诉内核“不要让我用x毫秒的处理器”。
简而言之,Sleep()会告诉操作系统在一段时间内忽略进程/线程。
'cin'使用了大量的重载操作符。 通常是右移位的'>>'在C ++中几乎每种类型的右手操作数都被重载。 为每一个函数提供一个独立的函数,它从控制台读取数据,并将输入转换成你给定的变量类型。 例如:
std::cin::operator>> (int &rhs);
这不是真正的C ++ – 我没有在一段时间内使用流和重载,所以我不记得返回类型或参数的确切顺序。 不过,这个函数在你运行cin >>一个整型变量时被调用。
确切的底层实现取决于操作系统。
答案取决于操作系统,但一般来说,操作系统要么安排一些其他代码在另一个线程的其他地方运行,或者如果它没有任何关系,就要等待CPU等待,直到发生硬件事件为止CPU跳转到一些称为中断处理程序的代码,然后可以决定运行哪些代码。
如果您正在寻找一种在多线程程序中阻塞线程/进程的更可控方法,请查看信号量,互斥锁,临界区和事件。 这些都是用来阻塞进程或线程的技术(不需要通过while构造加载CPU)。
它们本质上是等待/信号习惯用语,其中被阻塞的线程正在等待,另一个进程发信号告诉它重新开始。 这些(至少在Windows中)也可以有超时,从而提供了类似于Sleep()的功能。
在较低的级别上,系统有一个称为“调度程序”的例程,它将所有正在运行的程序的指令发送到实际运行它们的CPU。 诸如“睡眠”和“休眠”之类的系统调用与指示IGNORE指示该线程或进程持续固定时间的指令相匹配。
至于C ++流,“cin”隐藏了你正在访问的实际文件句柄(stdin和stdout实际上就是这样的句柄),而它的“>>”操作符隐藏了底层的读写操作。 由于其接口的实现可以是特定于操作系统,但从概念上讲,它仍然在做printf和scanf之类的东西。