线程标识和进程标识之间的关系

我在进程ID和线程ID之间有一些混淆。 我在这里经历了几个包括堆栈溢出的networkingpost,其中说

开始一个新的进程给你一个新的PID和一个新的TGID,而开始一个新的线程给你一个新的PID,同时保持相同的TGID。

所以当我运行一个程序时,为什么从程序创build的所有线程都没有不同的PID?

我知道在编程中我们通常会说main是一个线程 ,执行从main开始,所以如果我从main创build多个线程,所有的线程将有相同的PID,它等于主的PID。

所以我想问的是如下:

1)当我们运行一个程序时,它将作为一个进程或线程运行?

2) 线程创build线程和进程创build线程是否有区别?

3)在Linux中的线程和进程有什么区别? 因为我读了一些linux不区分Thread和Process的地方。

Solutions Collecting From Web of "线程标识和进程标识之间的关系"

简化一下:

  1. PID是进程ID,TID是线程ID。 关于由fork()创建的第一个线程,PID = TID。 如果在进程中创建更多的线程,使用clone()命令,那么PID和TID将会不同,PID将始终小于TID。

  2. 不,没有什么区别,除了如果main被杀,所有其他线程也被杀死。

  3. 是的,该线程是实际上预定的。 从技术上讲,这个过程只是不同代码段(text,bss,stack,heap和OS)的内存映射。

这种混淆来自于Linux的任务概念。

在Linux中,任务和线程之间几乎没有区别。

每个进程都是一个独立的虚拟机,至少运行一个任务。

每个任务都是流程范围内的独立执行单元。

进程的主要任务是为进程提供任务ID(TID),因为它是进程ID(PID)。

在流程中产生的每个新线程都会在其中创建一个新任务。 为了在内核中单独识别,他们被分配了他们自己的个人任务ID(TID)。

一个进程中的所有任务共享相同的任务组ID(TGID)。

您已经显示的帖子描述了Linux线程实现,我认为这是Linux实现的老版本,其中线程被创建为不同的进程。 在线程的POSIX实现中,线程不是作为一个不同的进程创建的,而是创建了不同的并行执行代码的流,这些并行执行的代码有些不同,这些并行执行中的信息由Thread Descriptor存储的TID 。 而创建多个线程的进程可以被称为多线程进程,因此具有与其所有线程相同的PID,但具有不同的TID。 主进程创建线程可以称为主线程

我在这里得到了答案在stackoverflow。 它指出,如果我们在Linux上运行一个包含libc libuClibc-0.9.30.1.so(1)的程序。 基本上libc的旧版本,然后创建的线程将有不同的PID,如下所示

 root@OpenWrt:~# ./test main thread pid is 1151 child thread pid is 1153 

我尝试用一​​个包含libc6(2)的libc的Linux来运行这个程序,也就是说libc的更新版本,然后创建的Thread将拥有与进程相同的PID。

 $ ./test main thread pid is 2609 child thread pid is 2609 The libc (1) use linuxthreads implementation of pthread 

而libc(2)使用pthread的NPTL (“Native posix线程库”)实现

根据linuxthreads FAQ(在J.3中的答案):

每个线程实际上是一个独特的PID过程,发送给线程PID的信号只能由该线程处理

所以在使用linuxthreads实现的旧libc中,每个线程都有其独特的PID

在使用NPTL实现的新libc版本中,所有线程都具有与主进程相同的PID。

NPTL是由红帽团队开发的。 根据国家红新月会文件 :NPTL实施中解决的问题之一是:

 (Chapter: Problems with the Existing Implementation, page5) 

Each thread having a different process ID causes compatibility problems with other POSIX thread implementations. This is in part a moot point since signals can't be used very well but is still noticeable

这就解释了这个问题。

我正在使用包含pthread的NPTL (“本地posix线程库”)实现的新的libc版本。

您将得到相同的进程ID,因为所有线程都共享您的程序数据,这是您的过程,所以当您调用进程ID时,您将得到相同的结果。