可以在单个处理器系统上实现多线程吗?


75

我一直遵循这样的概念,即多线程只能在多处理器系统上实现,在该系统上,每个线程分配一个以上的处理器,并且每个线程可以同时执行。在这种情况下,没有调度,因为每个线程都有各自专用的资源。但是我经常在一个可以在单处理器系统上执行多线程的地方阅读它。这是对的吗?如果是,那么单处理器和多处理器系统之间有什么区别?


9
是的,简单地说,是感知并发与实际并发。
WhozCraig 2013年

9
如果不可能,那么Windows 95就是一种幻觉。(如果您将多处理视为多线程,那么原始的unix也是一种幻觉。)
Raymond Chen

[链接](qnx.com/developers/docs/qnxcar2/…)图片比文字更强大
LinconFive

Answers:


71

当然,它可以在单处理器系统上完成,实际上,这种方法要容易得多。它的运行方式与运行多个进程相同-内核通过计时器中断或其他类似机制挂起一个进程,保存其计算机状态,然后用先前保存的另一个状态替换该状态-唯一的区别是两个同一进程的线程共享相同的虚拟内存空间,从而使任务切换更加高效。

实际上,在多处理器系统上进行多线程处理要困难得多,因为存在从多个cpus /内核同时访问内存的问题,以及由此引起的所有讨厌的内存同步问题。


非常感谢。这很有帮助
Ayse

4
不,您一定误会了,因为您所解释的陈述肯定是错误的。
R .. GitHub停止帮助ICE 2013年

3
⁺¹表示“定时器中断”。整个Internet都没有提及切换是如何在硬件中完成的。我以为这是一个计时器,但即使是维基百科也没有提及。
Hi-Angel

如果在一个处理器上运行2个线程...是否不需要同步?

得到了@Barath帖子的答案。

73

我在某个可以在单处理器系统上执行多线程的地方也曾阅读过它。这是对的吗?如果是,那么单处理器和多处理器系统之间有什么区别?

是的,您可以在单个处理器系统上执行多线程。

在多处理器系统中,多个线程在不同的内核上同时执行。例如-如果有两个线程和两个核心,则每个线程将在单个核心上运行。

在单处理器系统中,多个线程执行一个接一个的执行,或者等待一个线程完成或被操作系统抢占,这取决于线程的优先级和操作系统策略。 ,相对于用户空间应用程序所需的应用程序响应时间。

时间比较(示例):

如果两个线程各自花费10us执行,那么在2处理器系统上,净时间为10us

如果两个线程每个执行花费10us,则在1个处理器系统上,净时间为20us


2
很有帮助。谢谢您:)
Ayse

9
Chrome在进程中运行标签,而不是线程。线程提高稳定性的说法是错误的。一个线程无法崩溃并使其余线程继续运行。由于进程的所有线程共享一个公共地址空间,因此任何一个线程破坏内存都可能影响它们。而且,由线程“崩溃”引起的非自愿终止会终止整个过程,而不仅仅是单个线程。
R .. GitHub停止帮助ICE

1
@R。好吧,我已经删除了有争议的部分。...也许我读得不够多,无法备份和证明线程的稳定性...
Barath Ravikumar

我看到线程“提高稳定性”的唯一方法是简化代码并减少错误发生的可能性。编写在自己的线程中运行的同步逻辑比异步,事件驱动的状态机逻辑要容易得多,这可以转化为更安全,更稳定的程序。但是,如果线程之一调用UB,则线程不会给您任何安全性。
R .. GitHub停止帮助ICE

4
我认为BarathBushan的答案很丰富,人们应该避免对此投反对票:(
Ayse 2013年

12

四核系统上可以有四个以上的活动线程。还有就是调度,除非你能保证进程不会尝试创建多个线程比有处理器。

是的,单核计算机上可以有多个线程。

单处理器系统与多处理器系统之间的区别在于,多处理器系统确实一次可以完成多项任务。它一次可以执行N项操作,其中N是处理器内核的数量。单处理器内核一次只能做一件事。正如WhozCraig在其评论中所说,这是实际并发与并发之间的区别。


非常感谢,我现在有了基本的想法
-Ayse

5

是的,您完全可以。以前(Win 95?),我们从协作多任务转向多线程,因为有人总是搞砸协作部分。您计算机上的每个程序都有至少一个线程。可能更多。CPU每秒仅在所有这些线程之间疯狂切换数百万次。如果它们都不起作用,它甚至可能会闲置一段时间。

多核系统仅意味着其中两个或多个线程可以并行运行。

但是,这样做可以减少很多麻烦。在单核计算机上使用多线程所做的全部工作就是模拟多任务处理。

Mulitasking足以防止由于长时间运行而导致GUI线程锁定。但是,除非您从编译器或Langauge获得一些帮助(例如C#async ... await),否则通常实现起来很复杂。结果,许多GUI程序员仅使用多线程和调用伪造多任务。如果该代码在单核或多核上运行,则不适合这样做。

最重要的是,多任务处理不适用于CPU限制的操作。但是,所有异步问题中有95%不受CPU限制。它们是网络或磁盘绑定。在单核计算机上,多线程也无法解决CPU受限的问题。如果有两个线程都需要100%的CPU时间(相同的编程或不同的线程),但只有一个内核可以运行它们,则CPU只需在两个线程都以49%的速度运行之间切换,而其余的2%则用于所有这些其他只做一点点的线程。

最后,实际上只有很少的问题是多线程的。只需尝试对Fibonacci序列(每对一个线程)进行多线程处理,而不必使其速度变慢,对内存的要求更高并且更加复杂。

tl; dr; 您需要多线程处理和多核计算机才能解决CPU受限的问题。大多数异步问题不受CPU限制。多任务处理就足够了。而且,即使在单核计算机上,您也可以使用线程完全执行多任务。


4

这是一个非常简化的示例。它实际上是我正在构建的程序的原型。它是在单线程中实现协作式多任务处理的一种实现。

main只需将quit标志设置为false,然后填充功能指针数组(任务),然后调用loop

loop用于setjmp设置非本地跳转的返回点(函数中跳转回执行中的先前位置),然后继续调用第一个任务(函数)。

每个任务都以结尾yield()。也就是说,实际上没有任何任务起作用return。它们不仅不包含一条return;语句(这很好,因为它们是void函数,即过程),而且return即使到达那里也不会到达,因为yield跳转回setjmp调用,这时该if语句的值为1在中loop。由该语句控制的if语句在重新进入while循环之前选择其他任务。

因此,每个任务功能都会运行多次,从而产生调度程序(该if(setjmp...语句),该调度程序选择要运行的新任务。

此示例与单处理器多任务计算机系统之间的区别在于,真正的处理器支持在执行过程中中断任务,并在以后从同一位置恢复该任务。在将任务作为单个功能的C模拟中,这实际上是不可能的。但是,这些任务可以由一系列C函数组成,每个C函数都产生给分派器(一个函数指针数组,或者一个链表)。


1
您能否添加某种形式的描述或评论,以准确解释这应该显示和执行的操作?谢谢。
Deanna

编辑有一些解释。(我可以根据需要添加更多内容。)
luser droog 2013年

1
看起来没有任何方法可以从中返回yield(),因此每个线程都必须在调用yield之前完成。因此,无法一次拥有多个活动线程,也无法在它们之间进行切换。因此,只需让任务返回(而不是调用yield)而根本不使用setjmp/ longjmp,就可以使事情变得更加简单。
克里斯·多德

0

在单个处理器上的多线程进程中,处理器可以在线程之间切换执行资源,从而导致并发执行。并发表示正在执行多个线程,但是实际上线程并没有同时运行。线程之间的切换发生得足够快,以至于线程似乎可以同时运行。

在共享内存多处理器环境中的同一多线程进程中,进程中的每个线程可以在单独的处理器上并发运行,从而导致并行执行,这是真正的同时执行。当进程中的线程数小于或等于可用处理器数时,操作系统的线程支持系统将确保每个线程在不同的处理器上运行。例如,在用四个线程编程并在具有两个双核处理器的系统上运行的矩阵乘法中,每个软件线程可以在四个处理器内核上同时运行,以同时计算一行结果。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.