1

我的第一个问题:根据标题。

我之所以问这个问题是因为我遇到了一个 StackExchange 问题:多个线程可以做哪些单线程不能做的事情?

在该链接中给出的解决方案之一中,无论多线程可以做什么,它也可以由单线程完成。

然而我不认为这是真的。我的论点是:当我们用套接字编程构建一个简单的聊天程序并通过命令控制台运行它时。如果聊天程序是单线程的。聊天程序实际上是半双工的。这意味着我们不能同时听和说,每次只有一方可以说话,另一方必须听。为了让双方能够同时交谈和接收消息,我们必须用多线程来实现它。

我的第二个问题:我的论点正确吗?还是我在这里遗漏了一些要点,因此单个线程仍然可以完成多线程所做的一切?

4

3 回答 3

4

让我们将计算机视为一个整体,更准确地说,您的聊天应用程序与内核(或整个操作系统)绑定在一起,我们称之为“软件”。

现在考虑这个“软件”在单核(比如 i386)上运行。

然后你会发现,即使你使用线程编写聊天应用程序(这可能有点过头了),软件作为一个整体运行在单个 CPU 内核上,这意味着它在某一时刻只执行一件事情,即使似乎有平行的事情发生。

这只不过是一台图灵机(使用单个磁带)https://en.wikipedia.org/wiki/Turing_machine

并行性是内核造成的一种错觉,因为它可以足够快地在任务之间切换。就像一部电影在银幕上看起来是连续的画面,而实际上每秒只有 24 幅画面,这足以愚弄我们的大脑。

所以我想说,多线程程序做的任何事情,单线程都可以做。

尽管如此,现在我们都使用多核 CPU,在某个时间点可以看作是同时在多台计算机上运行(并行计算),因此您可能会找到在多核上运行但不会在多核上运行的软件单线程的。一个很好的例子是设备驱动程序(在内核中)。如果你的实现很差,在非抢占式内核上,你可以创建一个无限期等待事件的繁忙循环。这通常在单核上死锁(您阻止内核调度另一个任务,因此您阻止发送事件)。但这可以在多核上工作,因为事件通常最终由在另一个核心上运行的另一个线程发送(希望如此)。

于 2015-11-27T10:33:07.987 回答
2

我想修改现有答案(+1):

您绝对可以在单个线程上运行多个并行 IO。IO 只不过是一个内核数据结构。当您启动 IO 时,操作系统会与硬件对话并告诉它做某事。然后,CPU 可以自由地为所欲为。完成后,硬件会回调操作系统。它发出一个中断,劫持 CPU 内核来处理完成通知。

这称为异步 IO,所有操作系统都提供它。

事实上,这就是具有许多连接的套接字程序的运行方式。他们使用异步 IO 将大量连接多路复用到一个小线程池中。

于 2015-11-27T20:48:41.907 回答
1

这个论点不正确的核心原因是微妙的。虽然确实只有单个线程、单个内核或单个网络接口,该特定组件只能在任何给定时间处理发送或接收,如果它不是关键路径,那么描述它是没有意义的整个系统为半双工。

考虑一个全双工的网络链接,需要 1 毫秒才能将一大块数据从一端移动到另一端。现在想象一下,我们有一个设备可以将数据放在链接上或从链接中删除数据,但不能同时进行这两种操作。只要处理发送或接收所需的时间远少于 1 毫秒,双向数据必须经过的这个单一文件路径不会以某种方式使链路半双工。仍然会有数据同时在两个方向移动。

在任何现实的聊天应用程序中,CPU 都不会是限制因素。所以不能一次做多件事不能使系统半双工。仍然可以同时在两个方向上移动数据。

对于典型负载下的典型聊天应用程序,无论实现是使用单个线程还是具有无限 CPU 资源的多个线程,系统的行为都不会有显着差异。CPU不会成为限制因素。

于 2015-11-27T20:55:17.810 回答