转:

Linux中,每个进程有一个pid,类型pid_t,由getpid()取得。Linux下的POSIX线程也有一个id,类型 pthread_t,由pthread_self()取得,该id由线程库维护,其id空间是各个进程独立的(即不同进程中的线程可能有相同的id)。Linux中的POSIX线程库实现的线程其实也是一个进程(LWP),只是该进程与主进程(启动线程的进程)共享一些资源而已,比如代码段,数据段等。

linux多线程环境下gettid() pthread_self() 两个函数都获得线程ID,可它们的返回值不一样。
linux使用进程模拟线程,gettid 函数返回实际的进程ID(内核中的线程的ID).
pthread_self 函数返回 pthread_create创建线程时的ID(POSIX thread ID).

为什么有两个thread ID:

线程库实际上由两部分组成:内核的线程支持+用户态的库支持(glibc)。Linux在早期内核不支持线程的时候,glibc就在库中(用户态)以线程(就是用户态线程)的方式支持多线程了。POSIX thread只对用户编程的调用接口作了要求,而对内核接口没有要求。linux上的线程实现就是在内核支持的基础上,以POSIX thread的方式对外封装了接口,所以才会有两个ID的问题。

在glibc中,pthread_self()返回的是THREAD_SELF,这是一个宏。其定义如下

# define THREAD_SELF \
({ struct pthread *__self; \
asm ("movl %%gs:%c1,%0" : "=r" (__self) \
: "i" (offsetof (struct pthread, header.self))); \
__self;})

这段代码返回了当前线程的descriptor(即struct pthread结构),pthread_self()得到的就是这个descriptor的地址, 也就是unsigned long int类型的pthread_t。知道了这一点就好办了,找到thread descriptor的定义:

 
struct pthread
{
...
pid_t tid;
...
}

接下来知道怎么做了吗?算好长度n,构造一个假的pthread结构。

 
struct pthread_fake
{
void *nothing[n];
pid_t tid;
};

用(struct pthread_fake *) pthread_self()->tid得到线程id了。

The man page for gettid says:

The thread ID returned by this call is not the same thing as a POSIX thread ID(i.e., the opaque value returned by pthread_self(3)).

gettid 和pthread_self的区别的更多相关文章

  1. gettid()和pthread_self()的区别

    Linux中,每个线程有一个tid,类型long,由sys_gettid()取得. Linux内核中并没有实现线程,而是由glibc线程库实现的POSIX线程.每个线程也有一个id,类型 pthrea ...

  2. gettid和pthread_self区别

    http://blog.csdn.net/rsyp2008/article/details/45150621 1 线程ID获取方法 Linux下获取线程有两种方法: 1)gettid或者类似getti ...

  3. getpid 与 gettid 与 pthread_self

    获取进程的PID(process ID) #include <unistd.h> pid_t getpid(void); 获取线程的TID(thread ID) 1)gettid或者类似g ...

  4. pthread_detach

    http://blog.csdn.net/scanery/article/details/7241890   感谢作者! 近来发现 在线程函数第一行调用 pthread_detach(pthread_ ...

  5. pthread_join与pthread_detach细节问题

    http://www.360doc.com/content/13/0106/09/9171956_258497083.shtml pthread_t    pthr; pthread_create(& ...

  6. 【Linux开发】彻底释放Linux线程的资源

    Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的.而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出 ...

  7. linux的pthread_self与gettid的返回值和开销的区别

    linux的pthread_self与gettid的返回值和开销的区别 linux的pthread_self与gettid的返回值和开销的区别 分类: 一些思考 2012-05-18 12:25 17 ...

  8. Linux下获取线程TID的方法——gettid()

    (转载)http://blog.csdn.net/delphiwcdj/article/details/8476547 如何获取进程的PID(process ID)? 可以使用: #include & ...

  9. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

随机推荐

  1. Socket连接时,端口是怎么分配的

    socket 客户端连接socket 的端口每个是唯一的,每个新的连接,端口号+1 从1024-65534 最大到65534 然后再开始循环 中间遇到已经使用的端口就跳过

  2. 如何将centos7自带的firewall防火墙更换为iptables防火墙

    用惯了centos6的iptables防火墙,对firewall太无感了,那么如何改回原来熟悉的iptables防火墙呢? 1.关闭firewall防火墙 [root@centos7 html]# s ...

  3. redhat7.3忘记root密码后如何重置root密码

    redhat7系如果忘记root密码,重置密码方法与redhat6系不同! 1.开机启动系统,在grub选择启动内核项时 按‘e’进入编辑模式 2.这时看到的参数并不全,要按上下键滚动显示, 3.在l ...

  4. PDO数据库类——对query()和exec()的异常监听

    PDO异常类中,query()和exec()方法中执行失败时,默认情况下,我们是无法知道,具体执行失败的原因. 那如果我们想要监听异常的话,肿么整呢? 只要使用setAttribute()方法,即可监 ...

  5. 用批处理设置 wifi 热点,复制保存成 bat 以管理员身份运行即可

    @echo offtitle Wifi 热点控制echo #注意:本文件需以管理员身份运行!# :Beginecho ========================echo 请选择操作:echo 1 ...

  6. Android(java)学习笔记97:使用GridView以及重写BaseAdapter

    1. BaseAdapter: 对于ListView.GridView.Gallery.Spinner等等,它是它们的适配器,直接继承自接口类Adapter的,使用BaseAdapter时需要重写很多 ...

  7. 几位it 前辈的博客

    赵劼 http://blog.zhaojie.me/?page=2 陈硕 http://www.cnblogs.com/Solstice/ 轮子哥 http://www.cnblogs.com/gen ...

  8. IOError: [Errno 22] invalid mode ('rb') or filename: 'F:\netData1.mat'

    这种错误的出现是在使用built-in函数file()或者open()的时候.或者是因为文件的打开模式不对,或者是文件名有问题.前者的话只需要注意文件是否可读或者可写就可以了.后者则是与文件路径相关的 ...

  9. treap数组版

    然而就是将指针的地方换成int引用 就是存个代码 #include<cstdio> #include<iostream> #include<cstdlib> #in ...

  10. P2341 [HAOI2006]受欢迎的牛

    P2341 [HAOI2006]受欢迎的牛 塔尔羊标准模板(我才不会告诉你我嘴里含着一个九省联考的出题人) 不会劈配.林克卡特树.制胡窜 我还会叉粪宿主,梳妆素组,西安段素 #include<c ...