2

今天我的老板和我正在讨论我写的一些代码。我的代码从给定的 HTTP/HTTPS 链接下载 3 个文件。我进行了多线程下载,以便所有 3 个文件在 3 个单独的线程中同时下载。在这次讨论中,我的老板告诉我,代码将交付给最有可能运行旧硬件和软件的人(我说的是 Windows 2000)。

在此之前,我从未考虑过线程应用程序如何在旧硬件上扩展。我意识到如果 CPU 只有 1 个核心,线程是无用的,甚至可能会降低性能。我一直想知道这个下载任务是否是 I/O 操作。意思是,如果一个 API 在等待来自 HTTP/HTTPS 服务器的信息时被阻塞,是否会同时调度另一个想要进行计算的线程?较旧的操作系统会进行这样的调度吗?

他说的另一件事是:由于代码将在旧机器上运行,我的应用程序不应该占用 CPU。他说Sleep()在 CPU 密集型任务之后使用调用来给其他程序一些喘息的空间。现在我总是觉得Sleep()在任何程序中使用都很糟糕。我错了吗?什么时候使用Sleep()合理?

感谢您的关注!

4

1 回答 1

5

我一直想知道这个下载任务是否是 I/O 操作。意思是,如果一个 API 在等待来自 HTTP/HTTPS 服务器的信息时被阻塞,是否会同时调度另一个想要进行计算的线程?较旧的操作系统会进行这样的调度吗?

是的,他们这样做。这就是阻塞 IO 的笑话。线程被挂起并进行其他计算(线程),直到有事件唤醒被阻塞的线程。这就是为什么即使对于单核机器也将其拆分为线程而不是在单个线程中自己在下载之间进行一些糟糕的人工调度是完全有意义的。

当然,您的下载在带宽方面会相互影响,因此线程不会帮助加快下载速度:-)

他说的另一件事是:由于代码将在旧机器上运行,我的应用程序不应该占用 CPU。他说,在 CPU 密集型任务之后使用 Sleep() 调用可以让其他程序有一些喘息的空间。

实际上在任务完成后使用睡眠在这里无济于事。在进行计算之前进行一定时间的计算(进行时间切片)后进行睡眠可能会有所帮助。但这仅适用于协作系统(例如 Windows 3.11)。这对于调度程序使用时间片将计算时间分配给线程的抢占式系统不起作用。在这里考虑降低 CPU 密集型任务的优先级以给予其他任务优先级会更重要......

现在我总觉得在任何程序中使用 Sleep() 都很糟糕。我错了吗?什么时候使用 Sleep() 是合理的?

这真的取决于你在做什么。如果您实施某种忙于等待设置的某个标志,该标志可能在几秒钟后设置,最好在休眠一段时间后重新检查它是否设置,以便放弃您预定的时间片,而不是仅仅消耗 CPU 功率检查从未设置的标志。

在现代系统中,在计算中引入睡眠是没有意义的,因为它只会减慢您的计算速度。

调度取决于操作系统的调度程序。他是拥有“大局观”的人。在我看来,每一种“做得更好”的方法都只在特定应用程序的范围内有效,在这个应用程序的范围内,您可以概览某些对调度程序来说并不明显的关系。

附录:我做了一些研究,发现 Windows 支持从Windows 95开始的抢占式多任务处理。Windows NT 系列(Windows 2000 所属的)始终支持抢先式多任务处理。

于 2013-02-13T17:34:34.550 回答