标签:参考 选择 http 接口 概念 切换 div 进程组id 线程
在Linux的top和ps命令中,默认看到最多的是pid (process ID),也许你也能看到lwp (thread ID)和tgid (thread group ID for the thread group leader)等等,而在Linux库函数和系统调用里也许你注意到了pthread id和tid等等。还有更多的ID,比如pgrp (process group ID), sid (session ID for the session leader)和 tpgid (tty process group ID for the process group leader)。概念太多可能很晕,但是只要对Linux的进程和线程的基本概念有准确的理解,这些ID的含义都迎刃而解。下面将介绍进程和线程的核心概念,并以一个示例程序来验证这些ID之间的关系。
Linux的进程和线程有很多异同点,可以Google下。但只要能清楚地理解一下几点,则足够理解Linux中各种ID的含义。
上述第一点说明是最基础的,也是最重要的。
初步理解各种ID。基本上按照重要程度从高到低,在分割线下方的IDs不太重要。
从上面的列表看出,各种ID最后都归结到pid和lwp(tid)上。所以理解各种ID,最终归结为理解pid和lwp(tid)的联系和区别。
下面的图是一张描述父子进程,线程之间关系的图。
上图很好地描述了用户视角(user view)和内核视角(kernel view)看到线程的差别:
需要指出的是,有时候在Linux中进程和线程的区分也是不是十分严格的。即使线程和进程混用,pid和tid混用,根据上下文,还是可以清楚地区分对方想要表达的意思。上图中,从内核视角出发看到了pid 44,是从调度单元的角度出发,但是在top或ps命令中,你是绝对找不到一个pid为44的进程的,只能看到一个lwp(tid)为44的线程。
下面利用一个示例程序来进一步理解pid和lwp(tid),以及利用格式化的ps命令打印出各种ID。下面的程序在main函数中创建了2个子线程,加上main函数这个主线程,一共有3个线程。在3个线程中分别打印pthread id, pid和lwp(tid),来验证pid和lwp(tid)的关系。
1 #include <unistd.h> 2 #include <sys/syscall.h> 3 #include <stdio.h> 4 #include <pthread.h> 5 6 #define gettidv1() syscall(__NR_gettid) // new form 7 #define gettidv2() syscall(SYS_gettid) // traditional form 8 9 void *ThreadFunc1() 10 { 11 printf("the pthread_1 id is %ld\n", pthread_self()); 12 printf("the thread_1‘s Pid is %d\n", getpid()); 13 printf("The LWPID/tid of thread_1 is: %ld\n", (long int)gettidv1()); 14 pause(); 15 16 return 0; 17 } 18 19 void *ThreadFunc2() 20 { 21 printf("the pthread_2 id is %ld\n", pthread_self()); 22 printf("the thread_2‘s Pid is %d\n", getpid()); 23 printf("The LWPID/tid of thread_2 is: %ld\n", (long int)gettidv1()); 24 pause(); 25 26 return 0; 27 } 28 29 int main(int argc, char *argv[]) 30 { 31 pid_t tid; 32 pthread_t pthread_id; 33 34 printf("the master thread‘s pthread id is %ld\n", pthread_self()); 35 printf("the master thread‘s Pid is %d\n", getpid()); 36 printf("The LWPID of master thread is: %ld\n", (long int)gettidv1()); 37 38 // 创建2个线程 39 pthread_create(&pthread_id, NULL, ThreadFunc2, NULL); 40 pthread_create(&pthread_id, NULL, ThreadFunc1, NULL); 41 pause(); 42 43 return 0; 44 }
注意编译的时候要利用-l指定library参数。
# gcc threadTest.c -o threadTest -l pthread
执行程序,结果如下:
# ./threadTest the master thread‘s pthread id is 140154481125184 the master thread‘s Pid is 20992 The LWPID of master thread is: 20992 the pthread_1 id is 140154464352000 the thread_1‘s Pid is 20992 The LWPID/tid of thread_1 is: 20994 the pthread_2 id is 140154472744704 the thread_2‘s Pid is 20992 The LWPID/tid of thread_2 is: 20993
上述结果说明pthread id是pthread库提供的ID,在系统级别没有意义。pid都是线程组leader的进程ID,即20992。而lwp(tid)则是线程ID,分别是20993和20994。
同时利用ps来查看结果,注意ps默认只打印进程级别信息,需要用-L选项来查看线程基本信息。
# ps -eo pid,tid,lwp,tgid,pgrp,sid,tpgid,args -L | awk ‘{if(NR==1) print $0; if($8~/threadTest/) print $0}‘ PID TID LWP TGID PGRP SID TPGID COMMAND 20992 20992 20992 20992 20992 30481 20992 ./threadTest 20992 20993 20993 20992 20992 30481 20992 ./threadTest 20992 20994 20994 20992 20992 30481 20992 ./threadTest
从上述结果中可以看到:
默认top显示的是task数量,即进程。
可以利用敲"H",来切换成线程。如下,可以看到实际上有96个线程。也可以直接利用top -H命令来打印线程情况。
ps的-L选项可以看到线程,通常能打印出LWP和NLWP相关信息。如下命令即可查看线程信息:
ps -eLf
pidstat -t 可以打印出线程之间的关系。
要在htop中启用线程查看,开启htop,然后按<F2>来进入htop的设置菜单。选择“设置”栏下面的“显示选项”,然后开启“树状视图”和“显示自定义线程名”选项。按<F10>退出设置。
注:MAC的F2按fn+F2。
理解Linux的进程,线程,PID,LWP,TID,TGID
标签:参考 选择 http 接口 概念 切换 div 进程组id 线程
原文地址:https://www.cnblogs.com/wipan/p/9488318.html