10

我在进程 ID 和线程 ID 之间有些混淆。我已经浏览了几个网络帖子,包括这里的堆栈溢出,其中说

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

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

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

所以我想问如下:

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

2)主线程创建线程和进程创建线程 有什么区别吗?

3)linux中的线程和进程有什么区别吗?因为我在某处读到 linux 不区分线程和进程。

4

5 回答 5

14

简化一点:

  1. PID是进程ID,TID是线程ID。问题是,对于由fork()PID=TID 创建的第一个线程。如果你在进程内创建更多线程,用一个clone()命令,那么PID和TID就会不同,PID总是小于TID。

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

  3. 是的,线程是实际安排的。从技术上讲,进程只是不同代码段(文本、bss、堆栈、堆和操作系统)的内存映射。

于 2013-10-30T09:57:37.507 回答
4

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

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

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

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

进程的主要任务将其任务 ID (TID) 作为进程 ID (PID) 提供给进程。

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

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

于 2013-10-30T09:59:02.437 回答
2

我在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

我尝试使用包含来自 ubuntu libc6 (2) 的 libc 的 linux 运行该程序,即更新版本的 libc 然后创建的线程将具有与进程相同的 PID。

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

而libc(2)使用NPTL("Native posix thread library")实现pthread

根据linuxthreads常见问题解答(在 J.3 答案中):

每个线程实际上是一个具有不同 PID 的不同进程,发送到线程 PID 的信号只能由该线程处理

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

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

NPTLredhat团队开发。并且根据redhat 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

这解释了这个问题。

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

于 2013-10-30T19:38:44.927 回答
1

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

于 2013-10-30T09:58:51.890 回答
0

您将获得相同的进程 ID,因为所有线程都在共享您的程序数据,这是您的进程,因此当您调用进程 ID 时,您会得到相同的。

于 2013-10-30T09:57:57.027 回答