Pthread库实际上是用户线程解决方案吗?

Men*_*phy 41 multithreading kernel pthreads

标题可能不够清晰,因为我不知道如何定义我的问题.

我理解Pthread是一个符合POSIX标准的线程库(关于POSIX,请参阅维基百科:http://en.wikipedia.org/wiki/Posix).它可以在类Unix操作系统中使用.

关于线程,我读到有三种不同的模型:

用户级线程:内核不知道它.用户自己创建/实现/销毁线程.

内核级线程:内核直接支持进程中的多个控制线程.

轻量级进程(LWP):由内核调度但可以与用户线程绑定.

你有没有看到我的困惑?当我调用pthread_create()创建一个线程时,我是否创建了一个用户级线程?大概吧.那么我可以说,Pthread为线程提供了用户级解决方案吗?它无法操纵内核/ LWP?

par*_*a91 29

@ paulsm4我对你的内核知道每件事的评论表示怀疑.在用户级线程的这个特定上下文中,内核不知道发生了这样的事情.用户级别线程的调度由用户自己维护(通过库提供的接口),内核最终只将单个内核线程分配给整个进程.内核会将进程视为单线程,其中一个线程的任何阻塞调用最终都会阻塞该进程的所有线程.请参阅http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm


pau*_*sm4 19

问:我了解Pthread是一个符合POSIX标准的线程库

答:是的.实际上,"Pthreads"代表"Posix线程":http: //en.wikipedia.org/wiki/Pthreads

问:它可以在类Unix操作系统中使用.

答:实际上,它适用于许多不同的操作系统......包括Windows,MacOS ......当然还有Linux,BSD和Solaris.

问:关于线程,我读到有三种不同的型号

现在你变得模糊了."线程"是一个非常通用的术语.有许多不同的型号.您可以通过许多不同的方式来表征和/或实现"线程".包括Java线程模型或Ada线程模型等内容.

问:当我调用pthread_create()来创建一个线程时,我是否创建了一个用户级线程?

答:是的:您在用户空间中所做的一切都在您自己的私有"用户空间"中受到"保护".

问:用户级线程:内核不知道它.

答:不.内核知道一切 :)

问:内核级线程:内核直接支持进程中的多个控制线程.

答:是的,有"内核线程"之类的东西.

而且,实际上,Linux使得内核线程得到了广泛的使用.例如,Linux系统中的每个进程都是"内核线程".并且每个用户创建的pthread也被实现为新的"内核线程".和"工作线程"一样(对于任何用户级进程都是完全不可见的).

但这是一个高级主题,您无需了解以便有效地使用pthread.这是一本很好的书,详细讨论了这个以及许多其他主题:

Linux内核开发,Robert Love

请记住:"Pthreads"是一个界面.它的实现方式取决于平台.Linux使用内核线程; Windows使用Win32线程等.

================================================== =========================附录:

由于人们似乎仍然在打这个老线程,我认为引用这篇文章会很有用:

/sf/answers/787862211/

Linux通常使用两种pthread实现: LinuxThreadsNative POSIX Thread Library(NPTL),尽管前者基本上已经过时了.2.6中的内核提供了NPTL,它提供了与SUSv3更接近的一致性,并且在有许多线程时表现更好.

您可以使用命令在shell下查询pthread的具体实现:

getconf GNU_LIBPTHREAD_VERSION

您还可以在Linux编程接口中获得更详细的实现差异.

"Pthreads"是一个基于Posix标准的.如何实现pthreads库将因平台和库以及库而异.

  • 你在这里制造一些混乱吗?1.原始海报从未询问有关Linux特定细节的信息2.内核并不知道所有内容,特别是在用户级线程的上下文中,因为它们不是由内核调度的,所以在这种情况下它们被库"Pthreads""切换".3."线程"一词是通用的.没错,但问题更多是关于线程上下文中的操作系统和应用程序接口,答案应该是关于所述抽象. (22认同)
  • 实际上,这个答案是错误的.内核确实*不知道用户空间线程; 如果创建一个需要通知内核的线程(通过系统调用),那么你的线程将不再是"用户空间".这里的正确答案包括http://stackoverflow.com/a/12169068/1424877和http://stackoverflow.com/a/27581327/1424877; 和http://stackoverflow.com/a/8639239/1424877是这个答案的正确部分的一个很好的表达(但缺乏Linux细节,使其他人真正有助于OP). (6认同)
  • 这个答案极具误导性。用户级线程对内核不可见。这就是 N:1 线程模型的全部内容。您可以在每一本基本操作系统概念书籍上阅读此内容,例如 Silberschatz 第 7 版或 Stallings 第 7 版。另外,还有三种线程模型,就像第一个用户描述的那样: N:1 模型:多个 ULT 映射到 KLT 1:1 模型:每个 KLT 一个 ULT。N:M 模型:一个 ULT 映射到一个 LWP,映射到多个 KLT。 (2认同)

小智 13

pthreads本身并不是一个真正的线程库.pthreads是特定线程库使用该平台上可用的并发资源实现的接口.所以在linux,bsd,solaris等上有一个pthreads实现,虽然接口(头文件和调用的含义)是相同的,但每个的实现都是不同的.

那么pthread_create实际上就内核线程对象而言,在OS和pthread库实现之间有所不同.在第一次近似时,您不需要知道(pthread抽象允许您不需要知道的东西).最终你可能需要看到"幕后",但对于大多数pthread用户来说,这是不必要的.

如果您想知道/ specific/pthread实现在特定操作系统上的作用,您需要澄清您的问题.例如,Solaris和Linux的功能非常不同.


Jun*_*Zhi 8

在Linux中,pthread 实现为轻量级进程.内核(v2.6 +)实际上是用NPTL实现的.让我引用维基内容:

NPTL是一个所谓的1×1线程库,由用户创建的线程(通过pthread_create()库函数)与内核中的可调度实体(在Linux情况下的任务)1-1对应.这是最简单的线程实现.

所以Linux内核中的pthread实际上是作为内核线程实现的.

  • 这应该是公认的答案。Linux 中的 Pthreads 是通过 NPTL 实现的,这实际上是一个一对一的线程模型。创建每个用户级线程后,都会有一个与其关联的内核级线程。这意味着使用 NPTL 实现的 Pthread 可以利用多核 CPU (3认同)

Yon*_*ren 6

我发现以前的答案并不像我希望的那样令人满意或清晰,所以这里是:

你打电话时

pthread_create(...)
Run Code Online (Sandbox Code Playgroud)

您总是创建一个新的用户级线程。假设有操作系统,总是有一个或多个内核线程......但让我们更深入地研究一下:

根据“操作系统概念”第10版,我们应该关注的实际分类(当涉及到线程库时)是用户级线程如何映射到内核线程(这就是问题的真正含义)。

这些模型是一对一(单个进程中的每个用户级线程都映射到不同的内核线程),多对一(线程库是“用户级”,因此单个进程中的所有不同线程都映射到单个内核线程,线程数据结构、上下文切换等在用户级别处理,而不是由操作系统处理(这意味着如果线程在某些 I/O 调用上阻塞,整个进程可能会阻塞),并且许多许多(介于两者之间,显然用户级线程的数量大于或等于它所映射到的内核线程的数量)。

现在,pthreads 是一个规范,而不是一个实现,并且实现确实取决于它所写入的操作系统。它可以是这些模型中的任何一种(请注意,“多对多”非常灵活)。

因此,举个例子,在 Linux 和 Windows(多年来最流行的操作系统,其中模型是“一对一”)上,实现是“一对一”。