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

时间:2011-12-26 21:14:51

标签: multithreading pthreads kernel

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

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

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

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

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

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

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

6 个答案:

答案 0 :(得分:28)

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

答案 1 :(得分:21)

  

问:我理解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 Kernel Development, Robert Love

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

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

由于人们似乎仍然在打这个旧帖子,我认为参考这篇文章会很有用:

  

https://stackoverflow.com/a/11255174/421195

     

Linux通常使用两种pthread实现:   LinuxThreadsNative POSIX Thread Library(NPTL),   虽然前者基本上已经过时了。 2.6提供的内核   NPTL,提供与SUSv3更接近的一致性,并执行   更好,特别是当有很多线程时。

     

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

     

getconf GNU_LIBPTHREAD_VERSION

     

您还可以在The Linux Programming Interface中获得更详细的实施差异。

“Pthreads”是基于Posix标准的。 pthreads库的实现方式因平台和库而异。

答案 2 :(得分:12)

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

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

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

答案 3 :(得分:6)

在Linux中,pthread是implemented as a lightweight process。内核(v2.6 +)实际上是用NPTL实现的。让我引用维基内容:

  

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

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

答案 4 :(得分:0)

Pthreads只是线程库的标准化接口。是创建OS线程还是轻量级线程取决于您使用的库。然而,我的第一个客户是你的线程是“真正的”操作系统级线程。

答案 5 :(得分:-1)

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

致电时

pthread_create(...)

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

根据“操作系统概念”第10版,我们应该查看的实际分类(涉及线程库时)是如何将用户级线程映射到内核线程(这才是真正的意思)。

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

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

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