【问题标题】:C++ - how does Sleep() and cin work?C++ - Sleep() 和 cin 是如何工作的?
【发布时间】:2010-11-08 00:35:13
【问题描述】:

只是好奇。 Sleep() 函数实际上是如何工作的(在 windows.h 中声明)?也许不仅仅是那个实现,而是任何人。我的意思是-它是如何实施的?它如何使代码在特定时间“停止”?也很好奇 cin >> 和那些实际工作。他们具体是做什么的?

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

【问题讨论】:

    标签: c++ windows multithreading blocking scheduler


    【解决方案1】:

    操作系统使用一种称为调度程序的机制来保持其管理的所有线程或进程良好地协同工作。

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

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

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

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

    由于操作系统仅在某些事情导致它抢占正在运行的进程后才恢复进程,例如我提到的进程让步或硬件定时器中断,sleep() 不是很准确,准确度取决于操作系统或硬件,但是它通常在一毫秒或多毫秒的数量级上。

    如果需要更高的准确性,或者等待时间很短,唯一的选择是使用您提到的繁忙循环结构。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 只是好奇。你自己怎么打这样的电话?如果您因为隐藏的实现而无法在 Windows 上运行,也许是一个 linux 示例?
      • GNU/Linux 符合 Posix 系统调用。 Posix 系统调用被指定为 C 函数,但通常它们只是底层系统调用的包装器。如果您查看 /usr/include/asm/unistd_32.h,您会看到 nanosleep() 存在系统调用。 sleep() 很可能是通过调用这个系统调用来实现的。在 Windows 上也有系统调用,但它们没有记录,因此几乎没有理由了解它们是如何工作的。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        这不是真正的 C++——我已经有一段时间没有使用流和重载了,所以我不记得返回类型或参数的确切顺序。然而,当你运行 cin >> 一个整数变量时,这个函数会被调用。

        具体的底层实现取决于操作系统。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

            如果您正在寻找一种在多线程程序中阻塞线程/进程的更可控的方法,请查看信号量、互斥量、关键部分和事件。这些都是用于阻塞进程或线程的技术(无需通过 while 构造加载 CPU)。

            它们基本上使用等待/信号习语,其中被阻塞的线程正在等待,另一个进程发出信号告诉它重新开始。这些(至少在 Windows 中)也可以有超时,因此提供了与 Sleep() 类似的功能。

            【讨论】:

            • 超时版本也可用于 POSIX 系统。
            【解决方案7】:

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

            对于 C++ 流,“cin”隐藏了您正在访问的实际文件句柄(stdin 和 stdout 实际上就是这样的句柄),而“>>”运算符隐藏了对读取和写入的底层调用。由于它是一个接口,因此实现可以是特定于操作系统的,但从概念上讲,它仍然在做一些事情,例如 printf 和 scanf。

            【讨论】:

              猜你喜欢
              • 2019-02-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-07-08
              • 1970-01-01
              • 2014-03-06
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多