我在进程ID和线程ID之间存在一些混淆。我已经浏览了几个网络帖子,包括堆栈溢出here,其中说
启动一个新进程会为您提供一个新的PID和一个新的TGID,而启动一个新线程会为您提供一个新的PID,同时保持相同的TGID。
因此,当我运行程序时,为什么从程序创建的所有线程都没有不同的PID?
我知道在编程中我们通常说 main是一个线程并且执行从main开始,所以如果我从main创建多个线程,所有线程将具有相同的PID,它等于主要的PID。
所以我想问的是如下:
1)当我们运行程序时,它将作为进程或线程运行吗?
2)主线程创建线程和进程创建线程之间有什么区别吗?
3)linux中的线程和进程有什么区别吗?因为我读到某个地方,linux没有区分线程和进程。
答案 0 :(得分:10)
简化一下:
PID是进程ID,TID是线程ID。问题是,对于fork()
创建的第一个线程,PID = TID。如果在进程中使用clone()
命令创建更多线程,则PID和TID将不同,PID将始终小于TID。
不,没有区别,除非主要被杀,所有其他线程也被杀死。
是的,线程是实际安排的。从技术上讲,该过程只是不同代码段(文本,bss,堆栈,堆和操作系统)的内存映射。
答案 1 :(得分:4)
这种混乱来自Linux的任务概念。
在Linux中,任务与线程之间几乎没有区别。
每个进程都是一个自包含的VM,至少运行一个任务。
每个任务都是流程范围内的独立执行单元。
进程的主要任务是将进程的任务ID(TID)作为进程ID(PID)。
您在流程中生成的每个新线程都会在其中创建一个新任务。为了在内核中单独识别它们,它们被分配了自己的个人任务ID(TID)。
进程中的所有任务共享相同的任务组ID(TGID)。
答案 2 :(得分:2)
我在stackoverflow上得到了答案here。它声明如果我们在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,然后创建的Thread将具有与进程相同的PID。
$ ./test
main thread pid is 2609
child thread pid is 2609
The libc (1) use linuxthreads implementation of pthread
libc(2)使用NPTL
(“原生posix线程库”)实现pthread
根据linuxthreads
常见问题解答(在J.3答案中):
每个线程实际上是一个具有不同PID的独特进程,发送到线程PID的信号只能由该线程处理
所以在使用libc
实现的旧linuxthreads
中,每个线程都有其不同的PID
在使用NPTL
实现的新libc版本中,所有线程都具有与主进程相同的PID。
NPTL
由redhat团队开发。并根据redhat NPTL document: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
(“Native posix线程库”)实现的新libc版本。
答案 3 :(得分:1)
您所展示的帖子描述了Linux线程实现,我认为这是Linux实现的旧版本,其中线程是作为不同的进程创建的。 在线程的POSIX实现中,线程不是作为不同的进程创建的,而是创建不同的代码并行执行流,这些代码的并行执行中有一些组件不同,其信息由存储TID的线程描述符存储。 。 创建多个线程的进程可以称为多线程进程,因此其所有线程但不同的TID具有相同的PID。创建线程的主进程可以称为主线程
答案 4 :(得分:0)
您将获得相同的进程ID,因为所有线程都在共享您的程序数据,因此当您调用Process ID时,您将得到相同的结果。