我们知道进程ID是操作系统调度的最小单位,有时候根据业务的需要,我们会使用到多线程技术,当创建了多个线程时,也会有一个线程ID,那这个线程ID和进程ID有什么不一样吗?

其中,线程组的线程ID是属于NPTL(Native POSIX Thread Library)线程库的范畴,属该线程库调度的标识;而调度器的进程ID则属于操作系统的最小调度单位.两者具有在本质上截然不同的意义和使用范围,值得注意!我们来看一个实验代码:线程执行函数thread1和thread2都只做一件事情,输出自己的线程组中的线程ID和被调度器调度的进程ID,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <pthread.h>
#include <sys/syscall.h> /* syscall(SYS_gettid); */ void *thread1();
void *thread2(); int main(int argc, char *argv[])
{
int flag;
pthread_t th1,th2;
flag=pthread_create(&th1,NULL,thread1,NULL);
if(flag != 0)
{
fprintf(stderr,"创建线程1失败[%s]\n",strerror(errno));
exit(0);
} flag=pthread_create(&th2,NULL,thread2,NULL);
if(flag != 0)
{
fprintf(stderr,"创建线程2失败[%s]\n",strerror(errno));
exit(0);
} printf("main进程ID是[%d]\n",getpid()); pthread_join(th1,NULL);
pthread_join(th2,NULL); return 0;
} void *thread1()
{
int tid = syscall(SYS_gettid); /* 被进程调度器调度的进程ID */
printf("这是线程thread1,线程组的线程ID是[%u], 调度器的进程ID = %d\n",(unsigned int)pthread_self(), tid);
/* 让线程不要退出,以便查看在proc下的线程信息 */
pause();
} void *thread2()
{
int tid = syscall(SYS_gettid); /* 被进程调度器调度的进程ID */
printf("这是线程thread2,线程组的线程ID是[%u], 调度器的进程ID = %d\n",(unsigned int)pthread_self(), tid);
/* 让线程不要退出,以便查看在proc下的线程信息 */
pause();
}

运行结果

发现属于NPTL的线程ID的数值非常大(3078654832,3068164976),而属于系统调度器的进程ID则紧跟主进程的进程ID(4180,4181)

在线程没有退出的情况下(使用pause进行模拟),可以使用ls -l /proc/[pid]/task命令查看该进程下的所属线程信息.因为procfs文件系统在task下会给进程的每一个线程都建立一个子目录,目录名称为该线程的被调度的ID.(PS: 使用命令ps -L -p 4179也可以查看)

发现该进程的目录下的确有4180和4181的线程目录.

从本质上来说,属于NPTL范畴的线程ID的类型是pthread_t,而它指向了一个类型为struct pthread的结构体,所以还是一个指针,理解成为一个地址也可以.

而被系统调度的进程ID的类型却是pid_t,它是能被列入到调度队列的.所以,两者还是有很大区别的.

命令ps -L -p 4179的执行结果

./threadid的状态是Sl+,S表示该进程是静止的,l表示是多线程或者克隆线程.

备注:进程或线程的状态列表

D    不可中断     Uninterruptible sleep (usually IO)
    R    正在运行,或在队列中的进程
    S    处于休眠状态
    T    停止或被追踪
    Z    僵尸进程
    W    进入内存交换(从内核2.6开始无效)
    X    死掉的进程

<    高优先级
    N    低优先级
    L    有些页被锁进内存
    s    包含子进程
    +    位于后台的进程组
    l    多线程,克隆线程

线程的2个ID的更多相关文章

  1. 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。如:ABCABCABC…… 依次递归

    import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.uti ...

  2. python启动线程查看线程的名称和id;python杀掉进程的方法

    def cpu_app(): print("CPU") #启动一个线程t=threading.Thread(target=cpu_app,args=()) t.daemon = T ...

  3. 第四题(迅雷笔试题):编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

    #include <iostream> #include <stdlib.h> #include <pthread.h> using namespace std; ...

  4. 线程、线程句柄、线程ID

     什么是句柄:句柄是一种指向指针的指针.我们知道,所谓指针是一种内存地址.应用程序启动后,组成这个程序的各对象是住留在内存的.如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 ...

  5. Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID

    /** * Returns the identifier of this process's user. * 返回此进程的用户的标识符. */ Log.e(TAG, "Process.myU ...

  6. 线程句柄和线程ID的区别

    ●CreateThread() API 用于创建线程. API 返回同时线程句柄,并通过参数得到线程标识符 (ID). 线程句柄有完全访问权创建线程对象. 运行线程时线程 ID 唯一标识线程在系统级别 ...

  7. 【windows 操作系统】线程句柄HANDLE与线程ID的关系

    什么是句柄 句柄是一种指向指针的指针.我们知道,所谓指针是一种内存地址.应用程序启动后,组成这个程序的各对象是住留在内存的.如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访 ...

  8. 查看JAVA进程中哪个线程CPU消耗最高

    一,在centos linux 上查看进程占用cpu过高 top  shift+h 查看哪个进程程消耗最高     二,查看JAVA进程中哪个线程消耗最高   2.1 导出java运行的线程信息   ...

  9. Spring的线程池ThreadPoolTaskExecutor使用案例

    1.Sping配置文件 <!-- 线程池配置 --> <bean id="threadPool" class="org.springframework. ...

随机推荐

  1. MFC编程入门之二十一(常用控件:编辑框Edit Control)

    上一节讲了静态文本框,本节讲的是编辑框(Edit Control)同样是一种很常用的控件,我们可以在编辑框中输入并编辑文本.在前面加法计算器的例子中已经演示了编辑框的基本应用.下面具体讲解编辑框的使用 ...

  2. Redis教程(四):Hashes数据类型

    转自:http://www.jb51.net/article/65240.htm 一.概述: 我们可以将Redis中的Hashes类型看成具有String Key和String Value的map容器 ...

  3. mac终端terminal快捷键:

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Hannotate SC" } span.s1 { } p.p1 { m ...

  4. javascript正则表达式

    引用:http://www.jb51.net/article/72192.htm

  5. 创建ajax异步对象方法

    ajax的xmlhttp对象创建: function createXmlHttp(){ var xmlHttp; try{ // Firefox, Opera 8.0+, Safari xmlHttp ...

  6. 《基于Apache Kylin构建大数据分析平台》

    Kyligence联合创始人兼CEO,Apache Kylin项目管理委员会主席(PMC Chair)韩卿 武汉市云升科技发展有限公司董事长,<智慧城市-大数据.物联网和云计算之应用>作者 ...

  7. jq点击小图 弹出大图(更新版)

    $(function(){ $(".fj1-consult").on("click",function(){ //设置弹框中图片的路径 $(".lay ...

  8. mybatis入门总结

    背景: 最近“大胆地”把原本一个通过简单的JDBC连接数据库进行修改和查找操作的小项目改成用mybatis了.. 周四得到任务,周一要完成的,说是要添加查询条件和添加查询字段,修改的字段也多了几个,才 ...

  9. 张艾迪:全面开放“A"计划

    全面开放A计划.放飞梦想.放飞世界 AOOOiA.global将全面开启"A"计划.与世界分享We Share .与世界一同探索求知.全面开放"A"计划:拉近世 ...

  10. CSS设置DIV背景色渐变

    div{ width: 200px; height: 200px; FILTER: progid:DXImageTransform.Microsoft.Gradient(gradientType=, ...