什么是"线程"(真的)?

ric*_*ard 218 multithreading process definition

我一直试图找到一个好的定义,并了解一个线程到底是什么.

似乎我必须遗漏一些明显的东西,但每当我读到一个线程是什么时,它几乎是一个循环定义,一个"线程是一个执行线程"或"一种分为运行任务的方法".呃呃.咦?

从我所读到的看来,线程并不是真正具体的东西,就像进程一样.它实际上只是一个概念.从我所理解的这种工作方式,处理器为程序(这已被称为一个执行一些命令执行的线程),那么当它需要切换到处理一些其他节目了一下,它存储状态的它正在某个地方执行的程序(线程本地存储),然后开始执行其他程序的指令.而来回.这样,一个线程实际上只是当前正在运行的程序的"执行路径之一"的概念.

与流程不同,流程确实是某种东西 - 它是资源的集合等.

作为一个定义的例子并没有真正帮助我...

来自维基百科:

"计算机科学中的一个线程是执行线程的缩写.线程是程序将(称为"拆分")本身划分为两个或多个同时(或伪同时)运行任务的一种方式.线程和进程不同于一个操作系统到另一个,但通常,一个线程包含在进程内,同一进程中的不同线程共享相同的资源,而同一多任务操作系统中的不同进程则不共享.

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

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

pwn*_*all 191

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

假设你正在读一本书,而你现在想休息一下,但是你希望能够从你停下来的确切位置回来并继续阅读.实现这一目标的一种方法是记下页码,行号和字号.因此,阅读书籍的执行环境就是这三个数字.

如果你有一个室友,并且她使用相同的技术,她可以在你不使用时拿走这本书,并从她停下的地方继续阅读.然后你可以把它拿回来,并从你所在的地方恢复.

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

在技​​术层面上,执行上下文(因此是一个线程)由CPU寄存器的值组成.

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

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

  • 一个更好的比喻会使人与CPU等同(两者都是_do_的东西),并将书与地址空间等同(两者都存在).这样,不同书籍中的书签就像不同过程中的线程.一本书有一个以上的书签就是多线程过程的模拟,这就是人们说"线程"时通常所说的.它适用于单处理器机器,但在谈到多处理时会有所分析.没有人关心哪个CPU执行函数f(),但是_does_关于哪个人读第11章. (17认同)

Ben*_*igt 135

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

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

实际上,指令指针的值和存储在该位置的指令足以确定指令指针的新值.对于大多数指令,这只是按指令的大小推进IP,但控制流指令以其他可预测的方式更改IP.IP所采用的值序列形成了通过程序代码编织的执行路径,从而产生了名称"线程".

  • @Richard:CPU寄存器的确切列表取决于体系结构,但指令指针和堆栈指针几乎是通用的.它们定义一个线程,只要该线程(寄存器值集)被加载到处理器内核中,该线程就是*running*.处理器正在获取线程所需的指令并更新线程寄存器.当需要上下文切换时,处理器将这组寄存器值保存到存储器中并加载属于不同线程的集合,通常作为中断服务逻辑的一部分. (15认同)
  • +1.线程不是比一组寄存器值更"具体"的东西. (8认同)
  • 什么"价值观"?这些是什么?他们如何定义_thread_? (6认同)
  • 谢谢Ben.这非常有帮助. (3认同)
  • 你好@BenVoigt.一些澄清,像我这样的新手可能会偶然发现:"处理器寄存器"是什么意思?"指令指针"和"堆栈指针"是什么意思? (2认同)
  • Google-fu:指令指针->是一个寄存器,保存接下来要执行的指令的内存地址。CPU 通过硬连线读取指令指针并执行该特定地址处的指令。处理器寄存器 -> 寄存器是CPU实际处理的值(例如变量值)所在的位置。堆栈指针 -> 是一个小寄存器,用于存储堆栈中最后一个程序请求的地址 (2认同)
  • “处理器寄存器的值集”不是线程。这是一个线程_上下文。_ 它是线程的一部分,但只不过是线程专用的所有变量(包括其整个堆栈)或描述线程的内核变量。计算机科学家会说“执行线程”是一个特定的操作序列——通过程序代码“线程化”的操作序列。我告诉菜鸟,线程就像一个执行您的指令的代理,并且您可以让多个这样的代理同时为您工作。 (2认同)

Joe*_*ams 42

进程就像两个人使用两台不同的计算机,他们在必要时使用网络共享数据.线程就像两个人使用同一台计算机,他们不必明确地共享数据,但必须小心轮流.

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

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

我想要理解的关键事项是:

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


Leo*_*313 42

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

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

螺纹是可以独立于其它代码执行的程序内的这样的指令序列.该图显示了这个概念: 在此输入图像描述

线程在同一进程地址空间内,因此,进程的内存描述中存在的大部分信息可以跨线程共享.

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

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

在这里,从图形上看,这个概念很有代表性.

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


cha*_*uur 28

我将使用ABRAHAM SILBERSCHATZ,PETER BAER GALVIN和GREG GAGNE的"操作系统概念"一书中的大量文本以及我对事物的理解.

处理

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

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

当我们启动一个应用程序时,我们创建一个执行实例.此执行实例称为进程.编辑:(根据我的解释,类似于类和类的实例,类的实例是一个进程.)

流程的一个示例是Google Chrome.当我们启动Google Chrome时,会产生3个进程:

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

渲染器进程包含用于呈现网页的逻辑.因此,它们包含处理HTML,Javascript,图像等的逻辑.作为一般规则,为在新选项卡中打开的每个网站创建新的渲染器进程,因此可以同时激活多个渲染器进程.

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

线

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

现在继续讨论线程的定义.

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

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

线程或执行线程是基本有序指令序列的软件术语,可以通过单个CPU核心传递或处理.

因此,如果Chrome应用程序中的渲染器进程对数组进行排序,则排序将在执行的线程/线程上进行.(关于线程的语法似乎让我感到困惑)

我对事物的解释

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

编辑: 我发现有助于提供更多背景信息的其他信息

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

并发计算:

来自维基百科:

并发计算是一种计算形式,其中在重叠时间段期间执行若干计算 - 同时 - 而不是顺序执行(一个在下一次启动之前完成).这是系统的属性 - 这可以是单个程序,计算机或网络 - 并且对于每个计算("过程")存在单独的执行点或"控制线程".

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

(1 + 3) + (4 + 5)
Run Code Online (Sandbox Code Playgroud)

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

  • 这是真实的答案 (5认同)
  • 帮了很多忙。这就是解释的样子。 (2认同)

vas*_*dmr 8

线程是一组可以执行的(CPU)指令。

\n

但为了更好地理解什么是线程,需要一些计算机体系结构知识。

\n

计算机所做的就是遵循指令并操作数据。\n RAM是保存指令和数据的地方,处理器使用这些指令对保存的数据执行操作。

\n

CPU有一些称为寄存器的内部存储单元。它可以使用这些寄存器中存储的数字执行简单的数学运算。它还可以在 RAM 和这些寄存器之间移动数据。以下是可以指示 CPU 执行的典型操作的示例:

\n
    \n
  • 将数据从内存位置 #220 复制到寄存器 #3
  • \n
  • 将寄存器 #3 中的数字与寄存器 #1 中的数字相加。
  • \n
\n

CPU 可以执行的所有操作的集合称为指令集。指令集中的每个操作都分配有一个编号。计算机代码本质上是代表CPU操作的数字序列,这些数字存储在RAM中。

\n

CPU 以永无休止的循环方式工作,始终从内存中获取并执行指令。该周期的核心是PC 寄存器,或程序计数器。它是一个特殊的寄存器,用于存储下一条要执行的指令的内存地址。

\n

CPU 将:

\n
    \n
  1. 从PC给出的内存地址获取指令,
  2. \n
  3. 将 PC 加 1,
  4. \n
  5. 执行指令,
  6. \n
  7. 返回步骤 1。
  8. \n
\n

可以指示 CPU 将新值写入 PC,从而导致执行分支或“跳转”到内存中的其他位置。并且这种分支可以是有条件的。例如,CPU 指令可能会说:“如果寄存器 #1 等于 0,则将 PC 设置为地址 #200”。这允许计算机执行如下操作:

\n
if\xc2\xa0 x = 0\n    compute_this()\nelse\n    compute_that()\n
Run Code Online (Sandbox Code Playgroud)\n

使用的资源来自计算机科学蒸馏

\n


Fli*_*per 6

这是从雅虎回答中获取的:

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

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

然而,简单地说,线程就像不同的“任务”。所以想想当你在做某事时,例如你在一张纸上写下一个公式。这可以被认为是一个线程。然后另一个线程是你在另一张纸上写其他东西。这就是多任务处理的用武之地。

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

我不确定如何处理线程的后勤。我确实记得听说过处理器在它们之间来回切换,但我对此不是 100% 确定,希望其他人可以回答这个问题。


hob*_*bbs 6

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

  1. 一个线程有一个独立的执行线程(即你可以从它那里进行上下文切换,然后返回,它会在原来的地方继续运行)。
  2. 一个线程有一个生命周期(它可以由另一个线程创建,另一个线程可以等待它完成)。
  3. 它可能比“过程”附加的包袱更少。

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

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


Val*_*adu 6

一个线程只不过是一个带有执行规则的内存上下文(或者 Tanenbaum 如何更好地放置它,资源分组)。这是一个软件结构。CPU 不知道线程是什么(这里有些例外,有些处理器有硬件线程),它只是执行指令。

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


Orb*_*bit 5

不幸的是,线程确实存在.线程是有形的东西.你可以杀死一个,其他人仍然会运行.您可以生成新线程....虽然每个线程不是它自己的进程,但它们在进程内部单独运行.在多核机器上,2个线程可以同时运行.

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

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