如何在Windows和Linux下获取linux 打印当前线程id的ID号

Linux_C(138)
Linux_C++(85)
最近一直在想:
如何确认两段代码是不是在同一个线程中执行的呢?
通过查看资料,发现一种比较简单的方法就是在代码中使用printf将当前线程的id打印出来。
而这也分成两种情况:
1. 如果是pthread,则使用,
#include &pthread.h&
pthread_t pthread_self(void);
2. 如果不是pthread,即是由内核创建的线程,则使用,
#include &sys/types.h&
pid_t gettid(void);
获取线程所在的进程的id,方法如下:
#include &sys/types.h&
#include &unistd.h&
pid_t getpid(void);
pid_t getppid(void);
所以,我们在代码中使用如下的语句打印:
printf(&\ntid=%lu, pid=%lu\n&, gettid(), getpid());
这样就能获取当前代码所在的线程和进程了。
根据打印出来的进程的pid,获取进程名的方法是:
ls -lh /proc/pid/exe
lrwxrwxrwx 1 root root 0 Jan& 1 20:48 /proc/pid/exe -& ...
查看thread id的方法有:
1. sh-3.2# ps -efL | grep process,
ps命令指定-L命令选项可以用来查看进程下所包含的所有线程。
2. sh-3.2# ls -l /proc/pid/task/
查看进程下当前有哪些task,这些task指的就是线程。
测试所遇到的实际状况:
1. 运行后发现两个线程虽然是同属于一个进程,但是使用如上两种方法查看线程时只能看到其中一个线程。
猜测是另一个线程已经退出了?有空时可以再确认一下。
2. 调用gettid()会出现编译错误,其原因是gettid是一个系统调用,在glibc中没有对应的库函数。
用户如果有需要,可以直接调用gettid所对应的系统调用。
推荐阅读:
Linux 多线程同步(信号量)&
Linux多线程──主线程和子线程分别循环一定次数&
Linux多线程──3个子线程轮流运行&
Linux多线程──生产者消费者&
Linux多线程──读者写者问题&
Linux基础编程 多线程中的互斥锁 pthread_mutex_lock&
Linux基础编程 多线程同步 pthread_cond_signal&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1393484次
积分:17447
积分:17447
排名:第352名
原创:294篇
转载:694篇
评论:189条
(1)(3)(1)(10)(2)(2)(10)(4)(3)(3)(9)(18)(10)(9)(21)(4)(23)(25)(7)(19)(33)(22)(12)(2)(8)(8)(3)(4)(9)(6)(4)(23)(23)(26)(39)(24)(12)(14)(7)(25)(24)(14)(1)(14)(5)(5)(6)(25)(30)(39)(62)(37)(61)(56)(31)(37)(5)(3)(3)(2)(3)(4)(1)(1)(3)(2)(17)(1)(4)(5)(1)(1)(9)(1)(3)(2)5237人阅读
Linux(14)
在linux2.4版本后,linux使用了NPTL作为自己的线程库,为了兼容POSIX标准,所以在内核task中有两个域tgid和tid,前者是进程id,后者是线程id。在linux上获得线程id的方法,目前我所知的有三种,当然这里的三种是指在用户态的程序中,否则除非自己写的kernel module, 都是调用编号224的系统调用实现的(2.6版本)。第一种: gettid(), man gettid 可以看到gettid的使用方式。&&& 使用时要先定义:_syscall0(pid_t, gettid)&&& 其中_syscall0是一个宏(由于参数的不同还有_syscall1,_syscall2...),定义如下:&&& #define _syscall0(type,name) /&&& type name(void) /&&& { /&&& long __ /&&& __asm__ volatile ("int $0x80" /&& //int 80, 软中断&&&&&&& &&& : "=a" (__res) /&&&&&&&&& //输入输出都用的eax&&&&&&& &&& : "0" (__NR_##name)); /&& //#define __NR_gettid 224&&& __syscall_return(type,__res); /&& //返回tid&&& }&&& 编译时,宏展开之后,相当于定义了一个pid_t gettid(void)函数,用内嵌汇编实现,在程序中就可以使用gettid()获得线程id了。第二种:syscall(), 名字叫syscall(),却是glibc中的库函数。&&& 使用方式:syscall(__NR_gettid), 其中__NR_gettid就是224,同上。&&& syscall的实现要到glibc中去找,不同的硬件平台有不同的实现版本,在i386上的实现在syscall.S中:&&& #include &sysdep.h&&&& .text&&& ENTRY (syscall)&&& &&& PUSHARGS_6&&& &&& /* Save register contents.& */&&& &&& _DOARGS_6(44)&&& &&& /* Load arguments.& */&&& &&& movl 20(%esp), %eax&&& /* Load syscall number into %eax.& */&&& &&& ENTER_KERNEL&&& &&& /* Do the system call.& */&&& &&& POPARGS_6&&& &&& /* Restore register contents.& */&&& &&& cmpl $-4095, %eax&&& /* Check %eax for error.& */&&& &&& jae SYSCALL_ERROR_LABEL&&& /* Jump to error handler if error.& */&&& L(pseudo_end):&&& &&& ret&&& &&& &&& /* Return to caller.& */&&& PSEUDO_END (syscall)&&& 其中ENTRY也是一个宏,展开了相当的长,主要用于在链接的时候让gcc能够"看见"并调用这段用汇编写成的syscall()函数。第三种:pthread_self()&&& 同样是一个glibc提供的函数,在linux的manual中说返回的是当前线程的thread ID.但是实际你看到的是一个很长的,似乎没有规律的值。什么原因得看看它的实现:&&& 在glibc中,pthread_self()返回的是THREAD_SELF,这又是一个宏&&& 定义如下&&& # define THREAD_SELF /& &&& ({ struct pthread *__&&& &&& &&& &&& &&& &&& &&&&& /&&&& &&& asm ("movl %%gs:%c1,%0" : "=r" (__self)&&& &&& &&& &&& &&&&& /&&& & : "i" (offsetof (struct pthread, header.self)));&&& &&& &&&&& /&&&& &&& __})&&& 这段代码返回了当前线程的descriptor,pthread_self()得到的就是这个descriptor的地址, 也就是unsigned long int类型的pthread_t。知道了这一点就好办了,找到thread descriptor的定义:&&& struct pthread&&& {&&& &...&&&&&&&& pid_&&& &...&&& }&&& &&& 接下来知道怎么做了吗?算好长度n,构造一个假的pthread结构。&&& struct pthread_fake&&& {&&& void *nothing[n];&&& pid_&&& };&&& 用(struct pthread_fake *) pthread_self()-&tid得到线程id了&&& 相比前两种做法,这种无疑是最繁琐的,但是同理,可以获取很多glibc中维护了,但是没有提供访问方法的数据。Pthread& 07/12/13
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:38912次
排名:千里之外
原创:15篇Linux(31)
#include &sys/syscall.h&
#define gettid() syscall(__NR_gettid)
gettid()的返回值就是线程ID号
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:588921次
积分:4703
积分:4703
排名:第4313名
原创:28篇
转载:107篇
评论:40条
(1)(1)(4)(9)(4)(2)(7)(9)(1)(4)(4)(22)(8)(28)(2)(1)(1)(9)(4)(3)(1)(1)(4)(4)(2)linux(14)
linux多线程环境下gettid() pthread_self() 两个函数都获得线程ID,但这2个ID有所不同
gettid是内核中的线程的ID:
POSIX thread ID可以在一个进程内唯一标识一个线程,但如果放到系统范围内的话就得用gettid了。
#include &sys/syscall.h&&span style=&white-space:pre&& &/span&// 需要包含这个头文件 inline pid_t
my_gettid()
// gettid是内核中的线程的ID
return syscall(SYS_gettid);
/*这才是内涵*/
pthread_self是POSIX thread ID:
创建线程函数返回的第一个参数就是&pthread_self()
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);&同时&pthread_detach,pthread_cancel等函数是需要POSIX
thread id为参数的
线程库实际上由两部分组成:内核的线程支持+用户态的库支持(glibc),Linux在早期内核不支持线程的时候glibc就在库中(用户态)以纤程(就是用户态线程)的方式支持多线程了,POSIX thread只要求了用户编程的调用接口对内核接口没有要求。linux上的线程实现就是在内核支持的基础上以POSIX
thread的方式对外封装了接口,所以才会有两个ID的问题。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:460777次
积分:4998
积分:4998
排名:第3908名
原创:57篇
转载:135篇
评论:100条
(1)(1)(1)(1)(5)(1)(3)(4)(10)(6)(1)(6)(7)(5)(1)(2)(1)(1)(1)(3)(4)(3)(8)(4)(10)(4)(4)(2)(6)(6)(6)(5)(3)(7)(6)(9)(10)(2)(1)(1)(13)(7)(2)(4)(8)温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(12822)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_083075',
blogTitle:'获取线程号 gettid()【原创】',
blogAbstract:'
author:张继飞
项目中寻找bug经常会用到gettid(),来获取线程号,判断问题出在哪个线程里面。对于gettid先来man一下。
GETTID(2)&&&&&&&&&&&&&&&&& Linux Programmer\'s Manual&&&&&&&&&&&&&&&& GETTID(2)
NAME&&&&&& gettid - get thread identification
SYNOPSIS&&&&&& #include &sys/types.h&&&&&&& #include &linux/unistd.h&&&&&&& #include &errno.h&',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:9,
publishTime:9,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:2,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'善良纯洁',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 linux 查看当前线程 的文章

 

随机推荐