什么是“线程”(真的)?


236

我一直在努力寻找一个好的定义,并了解线程的真正含义。

看来我肯定缺少一些明显的东西,但是每次我读到什么是线程时,它几乎都是一个循环定义,例如“线程是执行线程”或“一种划分运行任务的方式”。嗯嗯 ??

从我阅读的内容来看,线程似乎并不是真正的具体东西,就像进程一样。实际上,这只是一个概念。根据我对这种工作方式的了解,处理器为程序执行一些命令(被称为执行线程),然后当需要切换到其他程序的处理时,它会存储处理器的状态。当前正在某处执行的程序(线程本地存储),然后开始执行其他程序的指令。来回。这样,线程实际上只是当前正在运行的程序的“执行路径之一”的概念。

与流程不同的是,流程实际上是某物-它是资源的集合等。

作为一个定义的例子并没有太大帮助。。。

维基百科

“计算机科学中的线程是执行线程的缩写。线程是程序将自身划分为两个(或多个)同时(或伪同时)运行的任务的方法。线程和进程不同于一个。操作系统,但通常情况下,一个进程中包含一个线程,并且同一进程中的不同线程共享相同的资源,而同一多任务操作系统中的不同进程则不共享。

那我说的对吗?错误?真正的线程是什么?

编辑:显然,一个线程也给出了自己的调用堆栈,所以这是有点的具体事情


6
“过程”至少是一个抽象术语。
霍布斯

线程本地存储只是线程的调用堆栈吗?
committedandroider


3
下面的答案是...摘要。用更简单的术语(并掩盖一些细节):从前,计算机程序一次只能做一件事。依次是A,B,C,...。在现代系统中,这不是理想的选择。例如,您要在下载文件时继续浏览网页。因此,程序现在具有一个或多个“线程”。每个“线程”一次只能做一件事情,但是不同的线程可以同时做一件事情。线程1可以先执行A,然后执行B,然后执行C;线程2可以先执行X,然后执行Y,然后执行Z。B在A完成之前无法启动,但是A和X 可以同时执行。
Mohan

@Mohan很棒,但是与流程有什么不同?
eric

Answers:


152

线程是处理器寄存器(用于单个内核)的一组独立的值。由于它包括指令指针(又称为程序计数器),因此它可以控制以什么顺序执行的内容。它还包括堆栈指针,堆栈指针最好指向每个线程的唯一内存区域,否则它们将相互干扰。

线程是受控制流(函数调用,循环,转到)影响的软件单元,因为这些指令在指令指针上操作,并且属于特定线程。线程通常是根据某些优先级分配方案进行调度的(尽管可以设计一个系统,每个处理器内核只有一个线程,在这种情况下,每个线程始终在运行,不需要调度)。

实际上,指令指针和存储在该位置的指令的值足以确定该指令指针的新值。对于大多数指令,这只是将IP扩大了指令的大小,但是控制流指令以其他可预测的方式更改了IP。IP所采用的值序列形成了一条贯穿程序代码的执行路径,从而产生了“线程”这个名称。


10
+1。线程比一组寄存器值更“具体”。
格雷格·休吉尔

6
什么是“价值集”?这些是什么?他们如何定义线程
理查德

20
@Richard:CPU寄存器的确切列表取决于体系结构,但是指令指针和堆栈指针非常通用。它们定义了一个线程,只要此线程(一组寄存器值)加载到处理器内核中时,该线程就处于运行状态。处理器正在获取线程所需的指令并更新线程寄存器。当需要上下文切换时,处理器会将这组寄存器值保存到内存中,并加载属于不同线程的一组值,通常将其作为中断服务逻辑的一部分。
Ben Voigt

4
谢谢本。这很有帮助。
理查德

2
谢谢@BenVoigt。像我这样的菜鸟可能会碰到的一些澄清:“处理器寄存器”是什么意思?“指令指针”和“堆栈指针”是什么意思?
BKSpurgeon '16

214

线程是执行上下文,它是CPU执行指令流所需的所有信息。

假设您正在读书,现在想休息一下,但是您希望能够回来并从停下来的确切位置继续阅读。实现此目的的一种方法是记下页码,行号和单词号。因此,您阅读本书的执行上下文是这3个数字。

如果您有一个室友,并且她正在使用相同的技术,则可以在不使用它时拿起这本书,然后从停下来的地方继续阅读。然后,您可以将其取回,并从您所在的位置恢复。

线程以相同的方式工作。CPU给您一种错觉,即它同时进行多个计算。它通过在每次计算上花费一些时间来做到这一点。之所以可以这样做,是因为每个计算都有一个执行上下文。就像您可以与朋友共享一本书一样,许多任务可以共享一个CPU。

从技术上讲,执行上下文(因此是线程)由CPU寄存器的值组成。

最后:线程与进程不同。线程是执行的上下文,而进程是与计算相关联的一堆资源。一个进程可以有一个或多个线程。

澄清:与进程关联的资源包括内存页(进程中的所有线程具有相同的内存视图),文件描述符(例如,打开的套接字)和安全凭证(例如,启动进程的用户的ID)处理)。


20
更好的类比是将人等同于CPU(两者做某事),将书等同于地址空间(两者均存在)。这样,不同书籍中的书签就像不同进程中的线程一样。一本带有多个书签的书将类似于多线程过程,这就是人们通常所说的“线程”。它适用于单处理器计算机,但是当您谈论多处理时,它会崩溃。无人问津其中CPU执行函数f(),但它确实不管哪个人读第11章
所罗门慢

@pwnall,非常感谢您为像我这样的其他人消化困难的概念!多线程是否参与了多处理(如果我使用了错误的术语,或者在多个CPU上并行运行一个进程)?
aerijman

51

为了正式定义线程,我们必须首先了解线程运行的边界。

当计算机程序从某个存储区加载到计算机的内存中并开始执行时,它就成为一个进程。进程可以由一个处理器或一组处理器执行。存储器中的过程描述包含重要信息,例如跟踪程序中当前位置(即当前正在执行哪条指令)的程序计数器,寄存器,变量存储,文件句柄,信号等。

螺纹是可以独立于其它代码执行的程序内的这样的指令序列。该图显示了概念: 在此处输入图片说明

线程位于同一进程地址空间内,因此,可以在线程之间共享进程的内存描述中存在的许多信息。

某些信息无法复制,例如堆栈(每个线程指向不同内存区域的堆栈指针),寄存器和特定于线程的数据。该信息足以允许独立于程序的主线程以及程序中可能的一个或多个其他线程来调度线程。

要运行多线程程序,需要明确的操作系统支持。幸运的是,大多数现代操作系统都支持线程,例如Linux(通过NPTL),BSD变体,Mac OS X,Windows,Solaris,AIX,HP-UX等。操作系统可能使用不同的机制来实现多线程支持。

在此以图形方式表示概念。

在这里,您可以找到有关该主题的更多信息。那也是我的信息来源。

让我补充从哪里来一句话介绍嵌入式系统爱德华·李Seshia

线程是同时运行并共享内存空间的命令性程序。他们可以访问彼此的变量。本领域的许多从业人员更狭义地使用术语“线程”来指代构建共享内存的程序的特定方式,[其他]则泛指命令式程序同时运行并共享内存的任何机制。从广义上讲,线程几乎以中断的形式存在于几乎所有微处理器上,即使根本没有任何操作系统(裸机)。


45

流程就像两个人使用两台不同的计算机,必要时它们使用网络共享数据。线程就像两个人使用同一台计算机,他们不必显式共享数据,但必须谨慎地轮流使用。

从概念上讲,线程只是在同一地址空间中嗡嗡作响的多个工蜂。每个线程都有自己的堆栈,自己的程序计数器等,但是进程中的所有线程共享相同的内存。想象两个程序同时运行,但是它们都可以访问相同的对象。

将此与流程进行对比。每个进程都有自己的地址空间,这意味着一个进程中的指针不能用于引用另一个进程中的对象(除非您使用共享内存)。

我猜要理解的关键是:

  • 进程和线程都可以“同时运行”。
  • 进程不共享内存(默认情况下),但是线程与同一进程中的其他线程共享所有内存。
  • 进程中的每个线程都有自己的堆栈和自己的指令指针。

您说“进程不共享任何东西(默认情况下)”,但以此类推,您说“进程就像两个人使用两台不同的计算机,他们在必要时使用网络共享数据”,那么它们确实共享某些东西吗?
committedandroider

@committedandroider:好电话。我编辑了答案,说进程不共享内存(默认情况下),但是线程共享所有内存。
乔伊·亚当斯

36

我将使用ABRAHAM SILBERSCHATZ,PETER BAER GALVIN和GREG GAGNE撰写的《操作系统概念》一书中的大量文字以及我对事物的理解。

处理

任何应用程序都以文本(或代码)的形式驻留在计算机中。

我们强调,程序本身不是过程。程序是被动实体,例如包含磁盘上存储的指令列表的文件(通常称为可执行文件)。

启动应用程序时,我们将创建执行实例。该执行实例称为流程。编辑:(根据我的解释,类似于类和类的实例,类的实例是一个过程。)

谷歌浏览器就是其中一个例子。启动Google Chrome时,会产生3个过程:

浏览器进程负责管理用户界面以及磁盘和网络I / O。启动Chrome后,会创建一个新的浏览器进程。仅创建一个浏览器进程。

渲染器进程包含用于渲染网页的逻辑。因此,它们包含用于处理HTML,Javascript,图像等的逻辑。通常,将为在新选项卡中打开的每个网站创建一个新的渲染器进程,因此几个渲染器进程可能会同时处于活动状态。

• 为使用中的每种类型的插件(例如Flash或QuickTime)创建一个插件过程。插件进程包含插件代码以及使插件能够与关联的渲染器进程和浏览器进程通信的其他代码。

线

为了回答这个问题,我认为您应该首先知道什么是处理器。处理器是实际执行计算的硬件。编辑:(计算如加两个数字,对数组排序,基本上执行已编写的代码)

现在转到线程的定义。

线程是CPU利用率基本单位 ; 它包括线程ID,程序计数器,寄存器集和堆栈。

编辑:来自英特尔网站的线程的定义:

线程(或执行线程)是可通过单个CPU内核传递或处理的基本指令顺序序列的软件术语。

因此,如果Chrome应用程序中的Renderer进程对数字数组进行排序,则排序将在执行线程上进行。(关于线程的语法对我来说似乎很混乱)

我对事物的解释

流程是一个执行实例。线程是通过CPU访问执行计算的实际工作者。当一个进程正在运行多个线程时,该进程将提供公共内存。

编辑: 我发现有助于提供更多上下文的其他信息

所有现代计算机都有多个线程。计算机中的线程数取决于计算机中的内核数。

并发计算

从维基百科:

并发计算是一种计算形式,其中在重叠的时间段内同时执行多个计算,而不是依次执行(一个计算在下一个开始之前完成)。这是系统的属性(可以是单个程序,计算机或网络),并且每个计算(“过程”)都有单独的执行点或“控制线程”。

因此,我可以编写一个计算4个数字之和的程序:

(1 + 3) + (4 + 5)

在用于计算该总和的程序中(这将是一个在执行线程上运行的进程),我可以派生另一个进程,该进程可以在不同的线程上运行以进行计算(4 + 5)并将结果返回到原始进程,而原始过程将计算(1 + 3)的总和。


5
才是

1
帮助很大。这就是解释的样子。
Dinesh Kumar '18

此答案的重要价值在于它提供了参考书,您可以在其中找到更多详细信息(如果需要)。谢谢@chatuur!
desa

7

不幸的是,线程确实存在。线程是有形的。您可以杀死其中一个,而其他将仍在运行。您可以生成新线程...。尽管每个线程都不是它自己的进程,但是它们在进程内部分别运行。在多核计算机上,可以同时运行2个线程。

http://en.wikipedia.org/wiki/Simultaneous_multithreading

http://www.intel.com/intelpress/samples/mcp_samplech01.pdf


1
是什么使它“切实可行”?仅仅是存储在TLS及其调用堆栈中的数据吗?
理查德

那不仅仅是理解的抽象……如果它实际上只是一个伪装成多个线程的来回线程,那么OP是正确的,但是是的,我要说的是,这些数据将使其有形。
轨道

开导我 。。。所以答案是什么?
理查德

@Richard不想参加关于语义的辩论,只是用我的回答来试图从概念上向OP澄清。
轨道

@richard的TLS是什么?
committedandroider

6

线程无非是带有执行规则的内存上下文(或Tanenbaum如何更好地将其称为资源分组)。这是一种软件结构。CPU不知道线程是什么(这里有些例外,某些处理器具有硬件线程),它只是执行指令。

内核引入了线程和进程概念,以有意义的方式管理内存和指令顺序。


5

这取自Yahoo答案:

线程是不受应用程序体系结构影响的编码构造。一个进程通常可能包含多个线程。线程也可以直接相互通信,因为它们共享相同的变量。

进程是具有各自状态信息的独立执行单元。它们还使用自己的地址空间,并且只能通过进程间通信机制与其他进程进行交互。

但是,简单来说,线程就像不同的“任务”。因此,想一想什么时候做某事,例如,您正在一张纸上写下一个公式。可以认为是一个线程。然后,另一个话题是您在另一张纸上写其他东西。这就是多任务处理的地方。

据说英特尔处理器具有“超线程”功能(AMD也具有),它的意思是能够更好地执行多个“线程”或多任务。

我不确定线程​​的处理方式。我确实记得有听说过处理器在它们之间来回走动的情况,但是我对此并不十分确定,希望其他人可以回答。


英特尔处理器如何更好地处理多线程?对于单个内核,一次只能执行一个线程。我同意处理器来回操作。您真的不能做得更好吗?
committedandroider

这是一项优化,可以为某些用例提供更好的性能。您可以在此处阅读有关超线程的信息: en.wikipedia.org/wiki/Hyper-threading
Jeremy Friesner 2015年

5

答案在不同的系统和不同的实现中差异很大,但是最重要的部分是:

  1. 线程具有独立的执行线程(即,您可以上下文切换离开它,然后再切换回去,它将在原先的位置继续运行)。
  2. 一个线程具有生命周期(可以由另一个线程创建,另一个线程可以等待它完成)。
  3. 它可能比“过程”具有更少的附加行李。

除此之外:线程可以由语言运行时在单个进程内实现,线程可以是协程,线程可以由线程库在单个进程内实现,或者线程可以是内核构造。

在包括我最熟悉的Linux在内的几个现代Unix系统中,一切都是线程-进程仅仅是一种线程,它与其父级共享相对较少的内容(即,它具有自己的内存映射,自己的文件表)和权限等)man 2 clone。在这里阅读(尤其是标志列表)确实很有启发性。


是仅当处理器从一个线程转到另一个线程时(无论是在同一进程中还是在另一个进程中)才进行上下文切换?
committedandroider

-1

我对这些答案都不满意,因此我将在此处添加自己的答案:)线程是内核的抽象,用于在处理器上调度工作,线程是内核为您提供的管理处理器时间的工具并与他人分享工作


1
-1不需要由内核创建线程。具有内核级别支持的线程确实是由内核调度的(发出某种类型的syscall)。但是也有一些具有用户库级别支持的线程,其中线程表位于用户空间中。
AleksandrH

-1

首先让我解释一下进程和线程之间的区别。

一个进程可以具有{1..N}个线程。关于虚拟内存和虚拟处理器的简短说明。

虚拟内存

用作交换空间,以便进程认为它位于要执行的主内存上。

虚拟处理器

与虚拟内存的概念相同,只是用于处理器。对于一个过程,看起来它是唯一正在使用处理器的东西。

操作系统将负责为进程分配虚拟内存和虚拟处理器,并在进程之间进行交换并执行。

进程中的所有线程将共享相同的虚拟内存。但是,每个线程将分配有各自的虚拟处理器,以便可以单独执行它们。

这样既节省了内存,又充分利用了CPU的潜力。

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.