zoukankan      html  css  js  c++  java
  • gettid 和pthread_self的区别

    转: 

    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)).

  • 相关阅读:
    UVaLive 7362 Farey (数学,欧拉函数)
    UVaLive 7361 Immortal Porpoises (矩阵快速幂)
    UVaLive 7359 Sum Kind Of Problem (数学,水题)
    CodeForces 706D Vasiliy's Multiset (字典树查询+贪心)
    负载均衡服务器
    集群-如何理解集群?
    架构规划
    领域模型
    状态图
    E-R图
  • 原文地址:https://www.cnblogs.com/iclk/p/4507756.html
Copyright © 2011-2022 走看看