首页 > 编程语言 > 详细

线程的2个ID

时间:2017-01-06 10:48:04      阅读:211      评论:0      收藏:0      [点我收藏+]

我们知道进程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

原文:http://www.cnblogs.com/foggia2004/p/6255163.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!