【问题标题】:Do user threads and kernel threads correspond to thread-level library and kernel-level library in any of the following ways?用户线程和内核线程是否与线程级库和内核级库有以下任何一种对应关系?
【发布时间】:2018-09-14 15:25:21
【问题描述】:

来自 Abraham Silberschatz、Greg Gagne 和 Peter Baer Galvin 的 Operating System Concepts,这里讨论了用户线程与内核线程:

可以在用户级别为用户提供对线程的支持 线程,或由内核,用于内核线程。

  • 用户线程是 在内核之上支持,并且在没有内核支持的情况下进行管理,

  • 内核线程直接由 操作系统。几乎所有当代运营 系统(包括 Windows、Linux、Mac OS X 和 Solaris)支持 内核线程。

最终,用户线程内核之间必须存在关系 线程。在本节中,我们将介绍三种常见的建立方法 这样的关系:多对一模型、一对一模型和 多对多模型。

这里是用于创建和管理线程的用户级库与内核级库的讨论:

线程库为程序员提供了一个 API,用于创建和 管理线程。实现线程有两种主要方式 图书馆。

  • 第一种方法是提供一个完全在用户空间中没有内核支持的库。库的所有代码和数据结构 存在于用户空间。这意味着在 库导致用户空间中的本地函数调用,而不是 系统调用。

  • 第二种方法是实现操作系统直接支持的内核级库。在这种情况下,代码和数据 库的结构存在于内核空间中。调用函数 在库的 API 中通常会导致系统调用 内核。

目前使用三个主要线程库:POSIX Pthreads、Windows、 和Java。 Pthreads,POSIX 标准的线程扩展,可以 以用户级或内核级库的形式提供。这 Windows 线程库是 Windows 上可用的内核级库 系统。 Java 线程 API 允许创建和管理线程 直接在Java程序中。然而,因为在大多数情况下,JVM 在主机操作系统之上运行,Java 线程 API 是 通常使用主机上可用的线程库来实现 系统。这意味着在 Windows 系统上,Java 线程通常是 使用 Windows API 实现; UNIX 和 Linux 系统经常使用 线程。

用户线程和内核线程与线程级库和内核级库的对应方式有以下几种吗?

  • 用户级库是否必须只创建和管理用户线程而不是内核线程?

  • 内核级库是否必须只创建和管理内核线程而不是用户线程?

  • 用户线程是否必须由用户级库而不是内核级库创建和管理?

  • 内核线程是否必须由内核级库而不是用户级库创建和管理?

书中说“Pthreads,POSIX 标准的线程扩展,可以作为用户级或内核级库提供。”

  • PThread 在 Linux 中是内核级库,在 Windows 中是用户级库吗?

  • PThread 是否根据定义创建和管理用户线程或内核线程?

谢谢。

【问题讨论】:

    标签: linux multithreading operating-system pthreads


    【解决方案1】:

    用户级库是否必须只创建和管理用户线程而不是内核线程?

    看来,这里的“用户级库”是指不依赖于允许创建和管理线程的内核系统调用的库,因此根据定义它不能创建内核线程。

    这里的想法是内核仍然不知道您正在进程中执行线程。这种方法的主要限制是这样的进程不能同时使用多个处理器内核。

    内核级库是否必须只创建和管理内核线程而不是用户线程?

    “内核级库”有点用词不当。库是一个用户空间的概念。在某些情况下,库函数和内核系统调用之间可能存在一一对应关系,但这通常不是最实用的解决方案。

    在 Linux 中,有一个 clone 系统调用可以创建一个新进程。这个新进程可以与父进程共享内存、文件描述符和其他资源。在高层次上,我们经常将这样的进程称为一个进程中的线程。直接使用系统调用通常是不必要的复杂性并且难以移植,因此通常使用用户空间库。

    通常使用的 pthread 实现是“内核级”,从某种意义上说,pthread 线程对应 1-1 到系统线程,但是在许多情况下,库函数调用不需要对应 1-1 到系统调用。特别是,最常用的函数是专门设计的,因此在大多数情况下它们不需要使用系统调用。它有助于提高性能。

    可以通过其他方式实现 pthread,但这似乎是最实用的。它将大多数选项留给库用户,因为内部或外部线程之间没有额外的间接级别。

    用户线程是否必须由用户级库而不是内核级库创建和管理?

    “用户线程”只是内核无法识别的类似进程的结构。 “内核级”库可能会使用类似的东西。也可以不使用任何库直接实现它们。

    内核线程是否必须由内核级库而不是用户级库创建和管理?

    内核线程的创建依赖于创建线程的系统调用。在大多数情况下,它会在库中使用,但原则上您可以直接调用它们。

    【讨论】:

    • 谢谢。在Linux中,PThread创建和管理的线程有哪些:内核线程,还是与内核线程一对一模型的用户线程?
    • @Tim,我认为这两种描述之间没有太大区别。从技术上讲,线程对库用户是可见的,因此您可以将它们称为用户线程,但是 1-1 对应关系允许我们放弃区分而只将它们称为线程。
    【解决方案2】:

    引用的命名法使 IMO 感到困惑。首先,Linux 和 Windows(以及我看过或研究过的大多数其他操作系统)没有用于实现其内部接口和数据结构的“库”。此外,库只是为了方便而捆绑在一起的代码体。因此,将库描述为一些基本和必要构建块(在内核或用户级别)是误导 IMO。

    话虽如此,实际上,所有系统确实当然都有库,以方便程序访问操作系统服务和/或相关代码体。一方面,系统调用通常是通过将参数加载到寄存器中并执行某种陷阱指令来将处理器切换到内核模式来实现的。由于几乎所有程序都是用高级语言编写的,因此通常无法直接将内容加载到寄存器中并执行陷阱指令。因此,很难看出在没有任何用户级库的情况下如何“管理”内核线程实现(通常)。我的观点是,基本上所有内核线程实现在某种程度上都需要用户级库的帮助。

    另一方面,一个纯粹的用户级线程实现可以在一个库中单独实现。事实上,这将是构建它的合乎逻辑的方式。

    线程是在 linux 和 Windows 的内核级别实现的。本机 Windows API 有自己的线程创建和管理工具,可通过 Windows 系统调用接口访问。 Linux 也有自己的机制,通过 its 系统调用接口实现。 posix 线程(pthreads)接口被实现为这两者之上的库。

    一般来说,pthreads 被认为是 linux 线程的 native 接口,尽管这并不是真的。 pthread 提供的功能包括线程的创建、销毁和管理,以及用于同步和进程间通信的许多机制。但是,用于实现这一点的底层系统调用包括像 clonefutex 这样通常不直接访问的关键构建块。用户层使用它们来提供 pthread 指定的行为。

    Windows 有自己独特的线程管理 API,它内置在“win32”库中,并使用 Windows 特定的系统调用来实现其行为。细节都不同(来自linux),它不符合pthreads规范。但是,您可以在本机库之上安装一个 second 库,该库将 Windows API 适配为与 pthreads 兼容的接口(它主要由 Windows 函数的包装器组成)。

    因此,对于这两个系统,pthreads 库在各自操作系统内核的帮助下创建和管理各种 pthread 指定的对象(在这两种情况下都使用内核线程实现)。

    最后,应该指出的是,Windows 也有一个真正的“用户级”线程实现,他们将其命名为“光纤”。 linux 中没有类似的东西(尽管过去的其他 Unix 实现包括用户级线程实现)。据我所知,Windows 的 pthreads 库不提供对光纤实现的访问。

    【讨论】:

    • 谢谢。在 Windows 中,pthread 是使用一对一还是多对一模型实现的(有关模型的定义,请参见cs.uic.edu/~jbell/CourseNotes/OperatingSystems/4_Threads.html),即是否只有一个或多个 pthread 线程对应于一个 Windows 内核线程? (注:在Linux中,只有一个pthread线程对应一个轻量级进程,所以是一对一的模型,如果我没记错的话)
    • 你说的linux是对的,在pthreads-win32实现中也是一对一的。它是 Windows 线程库的直接包装器。您可以在sourceware.org/pub/pthreads-win32/sources 找到它的源代码
    猜你喜欢
    • 2022-08-15
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 2017-05-04
    • 2015-04-08
    • 2018-04-06
    相关资源
    最近更新 更多