一个CPU处理器是否总是至少有一个线程?

19
我知道线程用于多任务处理,而且它们非常轻量级。
假设我需要一个没有任何多任务处理的进程。如果我只创建一个进程,CPU会将一个单独的线程与该进程关联,还是会执行该进程而不需要线程的存在?
2个回答

25
这取决于你所谈论的操作系统,但对于许多操作系统来说,创建进程的过程包括创建一个线程。
然后,该线程可以自由地创建属于该进程的其他线程。
谈论没有线程的进程几乎没有意义,因为这意味着该进程没有正在运行的代码,因此它无法做任何有用的事情。而且,如果你希望进程能够执行任何有用的工作,它将无法创建该进程的第一个线程。 :-)
举个例子,在Linux内核中,创建进程与创建新线程的方式略有不同。这是因为内核调度的是线程,而不是进程。
现在,进程被视为具有相同线程组ID(TGID)的线程组,而该TGID是为该进程创建的第一个线程的线程ID(TID)。
当你使用forkvfork或者clone(不带CLONE_THREAD)时,你会得到一个具有新TID的新线程,而TGID被设置为该TID - 这是一个新进程。
当你使用cloneCLONE_THREAD一起时,你会得到一个具有新TID的新线程,但TGID与克隆者保持相同。这是同一进程中的不同线程。
这就是Linux(以此为例)在不使调度器过于复杂的情况下区分进程和线程的方式。调度器可以选择完全忽略线程组。实际上,这非常聪明。
对于存在于调度器之外的代码来说,具有相同TGID的一组线程被视为一个进程(该代码所看到的进程ID就是该TGID)。
这包括用户空间代码和内核的其他部分,因为例如,线程如何分组到进程中会影响信号传递和退出代码等事项。

好的。那么,即使是执行单个任务,我们也需要一个线程,对吗?如果没有线程,仅使用进程执行单个任务(而不是多个任务)是不可能的。对吗? - Harish
1
@Harish,是的,必须有“某些东西”在运行。可能会有一些操作系统区分可运行的进程和可运行的线程,但我从未见过除了用户模式线程(其中线程根本不是由操作系统完成)之外的情况。通常,一个进程有一个或多个线程。 - paxdiablo
@paxdiablo,我对这部分有些疑问:“如果愿意,调度程序可以完全忽略线程组。” 我的印象是由于上下文切换(准确地说是保存状态),调度程序实际上无法忽略线程组。您能否再详细解释一下? - MK_Dev
@MK_Dev,上下文切换是发生在线程而不是线程组中的事情。调度程序只调度前者,并不需要担心线程可能属于哪个组。 - paxdiablo
@paxdiablo,谢谢,我明白了。从不同的线程组切换线程时,会有更多的性能损失,因为需要保留和恢复更多的状态吗?我的理解是,因为同一组中的线程共享内存,所以切换这些线程的成本会更低,因为只需要保留特定于特定线程的状态。 - MK_Dev
@MK,内存本身通常不是被切换的事情之一。但是内存句柄可能会被切换,这并不会增加太多开销,甚至可以为同一组中的线程执行此操作(我需要检查一下)。 - paxdiablo

5

一个进程就是一个线程。

当一个进程开始时,它会有一个单一的线程。

在多线程出现之前,线程这个术语是不必要的,因为一个进程不能有超过一个线程。

现在,你可以创建额外的线程,因此可以拥有具有多个线程的进程。

一个进程也是其他许多东西的集合 - 内存、堆栈等;其中之一就是线程。这些线程共享进程中的某些东西(例如内存),但具有自己的其他实例(例如堆栈)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接