C++ - Sleep() 和 cin 如何工作?
只是好奇。 Sleep() 函数实际上是如何工作的(在 windows.h 中声明)? 也许不仅仅是那个实现,而是任何人。 我的意思是 - 它是如何实施的? 它如何使代码“停止”特定时间? 也很好奇cin是如何>> 这些实际上有效。 他们具体是做什么的?
我知道如何“阻止”某些内容继续运行的唯一方法是使用 while 循环,但考虑到与调用从 stdin 读取的方法时发生的情况相比,这需要大量的处理能力(只需比较一段时间(true)从标准输入读取),我猜这不是他们所做的。
Just curious. How does actually the function Sleep() work (declared in windows.h)? Maybe not just that implementation, but anyone. With that I mean - how is it implemented? How can it make the code "stop" for a specific time? Also curious about how cin >> and those actually work. What do they do exactly?
The only way I know how to "block" something from continuing to run is with a while loop, but considering that that takes a huge amount of processing power in comparison to what's happening when you're invoking methods to read from stdin (just compare a while (true) to a read from stdin), I'm guessing that isn't what they do.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
操作系统使用一种称为调度程序的机制来保持它管理的所有线程或进程一起良好地运行。
计算机的硬件时钟每秒会多次中断 CPU,从而导致操作系统的调度程序被激活。 然后,调度程序将查看所有尝试运行的进程,并决定下一个时间片运行哪个进程。
它用来决定的不同内容取决于每个进程的状态以及它之前已经有多少时间。 因此,如果当前进程一直在大量使用CPU,导致其他进程无法取得进展,它会让当前进程等待并交换到另一个进程中,以便它可以做一些工作。
但更常见的是,大多数进程将处于等待状态。 例如,如果一个进程正在等待来自控制台的输入,操作系统可以查看进程信息并查看其正在等待哪些 io 端口。 它可以检查这些端口,看看它们是否有任何可供进程使用的数据。 如果这样做,它可以再次启动该过程,但如果没有数据,则在当前时间片内跳过该过程。
至于
sleep()
,任何进程都可以通知操作系统它想等待一段时间。 然后,调度程序甚至会在硬件中断之前被激活(这也是当进程尝试从没有准备好读取的数据的流中执行阻塞读取时发生的情况),并且操作系统会记录该进程的状态等待。 对于睡眠,进程正在等待警报响起,或者每次重新启动时它可能会再次屈服,直到计时器到时。由于操作系统只有在某些原因导致它抢占正在运行的进程后才恢复进程,例如我提到的进程让出或硬件定时器中断,
sleep()
不是很准确,准确程度取决于操作系统或硬件,但通常约为一毫秒或更多毫秒。如果需要更高的准确性或非常短的等待时间,唯一的选择是使用您提到的繁忙循环结构。
The OS uses a mechanism called a scheduler to keep all of the threads or processes it's managing behaving nicely together.
several times per second, the computer's hardware clock interrupts the CPU, which causes the OS's scheduler to become activated. The scheduler will then look at all the processes that are trying to run and decides which one gets to run for the next time slice.
The different things it uses to decide depend on each processes state, and how much time it has had before. So if the current process has been using the CPU heavily, preventing other processes from making progress, it will make the current process wait and swaps in another process so that it can do some work.
More often, though, most processes are going to be in a wait state. For instance, if a process is waiting for input from the console, the OS can look at the processes information and see which io ports its waiting for. It can check those ports to see if they have any data for the process to work on. If they do, it can start the process up again, but if there is no data, then that process gets skipped over for the current timeslice.
as for
sleep()
, any process can notify the OS that it would like to wait for a while. The scheduler will then be activated even before a hardware interrupt (which is also what happens when a process tries to do a blocking read from a stream that has no data ready to be read,) and the OS makes a note of what the process is waiting for. For a sleep, the process is waiting for an alarm to go off, or it may just yield again each time it's restarted until the timer is up.Since the OS only resumes processes after something causes it to preempt a running process, such as the process yielding or the hardware timer interrupt i mentioned,
sleep()
is not very accurate, how accurate depends on the OS or hardware, but it's usually on the order of one or more milliseconds.If more accuracy is needed, or very short waits, the only option is to use the busy loop construct you mentioned.
操作系统安排进程如何运行(哪些进程有资格运行、以什么顺序运行……)。
Sleep()
可能会发出一个系统调用,告诉内核“不要让我使用处理器 x 毫秒”。The operating system schedules how processes run (which processes are eligible to run, in what order, ...).
Sleep()
probably issues a system call which tells the kernel “don't let me use the processor for x milliseconds”.简而言之,Sleep() 告诉操作系统暂时忽略进程/线程。
In short, Sleep() tells the OS to ignore the process/thread for a while.
'cin' 使用大量重载运算符。 “>>”通常是右位移位,对于 C++ 中几乎所有类型的右侧操作数都会重载。 为每个变量提供了一个单独的函数,它从控制台读取并将输入转换为您给定的任何变量类型。 例如:
这不是真正的 C++——我已经有一段时间没有使用流和重载了,所以我不记得返回类型或参数的确切顺序。 尽管如此,当您运行 cin >> 时会调用此函数。 一个整数变量。
确切的底层实现取决于操作系统。
'cin' uses a ton of overloaded operators. The '>>', which is usually right bit-shift, is overloaded for pretty much every type of right-hand operand in C++. A separate function is provided for each one, which reads from the console and converts the input into whichever variable type you have given. For example:
That's not real C++ — I haven't worked with streams and overloading in a while, so I don't remember the return type or the exact order of arguments. Nevertheless, this function is called when you run cin >> an integer variable.
The exact underlying implementation depends on the operating system.
答案取决于操作系统,但一般来说,操作系统要么调度一些其他代码在另一个线程的其他地方运行,要么如果它实际上没有什么可做的,它会让CPU等待直到硬件事件发生,这会导致CPU 跳转到一些称为中断处理程序的代码,然后由中断处理程序决定运行哪些代码。
The answer depends on the operating system, but generally speaking, the operating system either schedules some other code to run elsewhere in another thread, or if it literally has nothing to do, it gets the CPU to wait until a hardware event occurs, which causes the CPU to jump to some code called an interrupt handler, which can then decide what code to run.
如果您正在寻找一种更受控制的方法来阻塞多线程程序中的线程/进程,请查看信号量、互斥体、关键部分和事件。 这些都是用于阻塞进程或线程的技术(不通过 while 构造加载 CPU)。
它们本质上是基于等待/信号惯用法,其中被阻塞的线程正在等待,另一个进程向它发出信号,告诉它重新启动。 这些(至少在 Windows 中)也可以有超时,从而提供与 Sleep() 类似的功能。
If you are looking for a more controlled way of blocking a thread/process in a multi-threaded program, have a look at Semaphores, Mutexes, CriticalSections and Events. These are all techniques used to block a process or thread (without loading the CPU via a while construct).
They essentially work off of a Wait/Signal idiom where the blocked thread is waiting and another process signals it to tell it to start again. These (at least in windows) can also have timeouts, thus providing a similar functionality to Sleep().
在底层,系统有一个称为“调度程序”的例程,它将指令从所有正在运行的程序分派到实际运行它们的 CPU。 “Sleep”和“usleep”等系统调用与告诉调度程序在固定时间内忽略该线程或进程的指令相匹配。
对于 C++ 流,“cin”隐藏了您正在访问的实际文件句柄(stdin 和 stdout 实际上就是这样的句柄),而“>>” 它隐藏了底层的读写调用。 由于它是一个接口,因此实现可以是特定于操作系统的,但从概念上讲,它仍然在幕后执行 printf 和 scanf 等操作。
At a low level, the system has a routine called the "scheduler" that dispatches the instructions from all the running programs to the CPU(s), which actually run them. System calls like "Sleep" and "usleep" match to instructions that tell the scheduler to IGNORE that thread or process for a fixed amount of time.
As for C++ streams, the "cin" hides the actual file handle (stdin and stdout actually are such handles) you're accessing, and the ">>" operator for it hides the underlying calls to read and write. Since its an interface the implementation can be OS-specific, but conceptually it is still doing things like printf and scanf under the hood.