进程ID与线程ID


进程ID与线程ID

在Linux中,进程和线程之间的关系有些特殊。传统的Unix系统(包括Linux)将线程实现为“轻量级进程”或“LWP”(Light Weight Process)。这意味着线程在内核中基本上被视为进程,但它们共享许多资源(如地址空间、文件描述符、信号处理器等)以提高效率。

  1. 线程组:在Linux中,当您创建一个新的线程时,该线程实际上是与原始进程(或主线程)在同一个“线程组”中的。线程组是一个或多个线程的逻辑集合,它们共享相同的进程ID(PID)和父进程ID(PPID)
  2. 主线程:线程组中的第一个线程通常被称为“主线程”或“原始线程”。当您使用fork()系统调用创建一个新进程时,该进程只有一个线程,即主线程。如果您在这个进程中调用pthread_create()或其他线程创建函数,那么新创建的线程将与主线程在同一个线程组中。
  3. 线程ID(TID)与进程ID(PID):每个线程在内核中都有一个唯一s的线程ID(TID)。但是,从外部看(例如,从用户空间或其他进程),线程组中的所有线程都共享相同的进程ID(PID)。这就是为什么主线程的TID(从内核的角度看)与其PID(从用户空间的角度看)相同的原因。当您使用像getpid()这样的函数时,您实际上获取的是线程组的PID,而不是特定线程的TID。
  4. 获取线程ID:要从用户空间获取特定线程的TID,您可以使用syscall(SYS_gettid)
  5. 线程组与进程的关系:尽管线程组中的线程共享许多资源,但它们仍然是独立的执行单元。这意味着它们可以有自己的调用栈、寄存器状态、线程本地存储(TLS)等。此外,线程可以有自己的调度优先级和调度策略。
  6. 信号处理:在线程组中的线程处理信号时,有一些特殊的考虑因素。例如,某些信号(如SIGSEGV)是线程特定的,而其他信号(如SIGTERM)则是进程级别的,并会发送给线程组中的所有线程

内核级线程ID和用户级线程ID

内核级线程ID是线程在内核中唯一的标识符

用户级线程ID是让我们用户来对线程进行区分的,它是pthread_create()函数的返回值,此ID本质上就是一个进程地址空间上的一个地址

您的描述非常准确。在Linux和许多其他操作系统中,线程管理在内核和用户空间层面有不同的表示和用途。

  1. 内核级线程ID(也称为线程ID或TID)

    • 线程ID是线程在操作系统内核中的唯一标识符。
    • 它通常由内核在创建线程时分配,并用于内核的各种管理目的,如调度、资源分配和信号处理。
    • 内核级线程ID对于用户空间程序通常是不直接可见的,除非程序使用特定的系统调用或API来获取它。
  2. 用户态线程ID(也称为pthread_t类型)

    • 用户态线程ID是POSIX线程库(pthread)为用户空间程序提供的线程标识符。
    • 当使用pthread_create()函数创建线程时,该函数会返回一个这种类型的值作为线程的标识符。
    • 这个ID在用户空间内是唯一的,但并不意味着它在系统范围内是唯一的(因为多个进程可以有相同ID的线程)。
    • 用户态线程ID本质上是一个不透明的数据类型,通常是一个指针或整数,用于在用户空间代码中引用和识别线程。在某些实现中,它可能确实指向进程地址空间中的一个特定位置,但这并不是必需的,也不应该由用户代码直接操作。
    • 这个用户级线程ID是线程库用于在用户空间内部管理和跟踪线程的一种方式。它允许用户代码使用诸如pthread_self()之类的函数来获取当前线程的ID,或者使用pthread_equal()来比较两个线程ID是否相同。

需要注意的是,尽管内核级线程ID和用户态线程ID在功能上是不同的,但它们之间通常存在某种映射关系。

  • POSIX线程库中,用户级线程和内核级线程之间的关系可能是一对一、多对一或多对多,这取决于线程库的实现和操作系统的支持。

  • Linux中,使用NPTL(Native POSIX Thread Library)线程库时,用户级线程和内核级线程通常是一对一的关系,即每个用户级线程都对应一个内核级线程。但在其他系统或线程库实现中,这种关系可能会有所不同。

参考:https://blog.csdn.net/dangzhangjing97/article/details/79860151

posted @ 2024-05-13 17:57  guanyubo  阅读(207)  评论(0编辑  收藏  举报