IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    获取POSIX线程真实PID/TID

    dutor发表于 2012-02-15 10:42:37
    love 0

      Linux中,每个进程有一个pid,类型pid_t,由getpid()取得。Linux下的POSIX线程也有一个id,类型pthread_t,由pthread_self()取得,该id由线程维护,其id空间是各个进程独立的(即不同进程中的线程可能有相同的id)。你可能知道,Linux中的POSIX线程库实现的线程其实也是一个进程(LWP),只是该进程与主进程(启动线程的进程)共享一些资源而已,比如代码段,数据段等。
      有时候我们可能需要知道线程的真实pid。比如进程P1要向另外一个进程P2中的某个线程发送信号时,既不能使用P2的pid,更不能使用线程的pthread id,而只能使用该线程的真实pid,称为tid。
      有一个函数gettid()可以得到tid,但glibc并没有实现该函数,只能通过Linux的系统调用syscall来获取。使用syscall得到tid只需一行代码,但为了加深各位看官的印象,简单提供下面场景。
      有一簇进程,其中一个进程中另外启了一个线程。各进程共享一个数据结构,由shared_ptr指明,其中保存有线程的tid。在各个进程的执行过程中,需要判断线程是否存在,若不存在则(重新)创建。
      首先,在线程函数的开始,需要将自己的tid保存至共享内存,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #include <sys/syscall.h>
    #include <sys/types.h>
    void*
    thread_func(void *args)
    {
        //~ lock shared memory
        shared_ptr->tid = syscall(SYS_gettid); //~ gettid()
        //~ unlock shared memory
        //~ other stuff
    }

      在各进程中判断进程是否存在,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    //~ lock shared memory
    pthread_t id;
    if (shared_ptr->tid == 0) { //~ tid is initialized to 0
        pthread_create(&id, NULL, thread_func, NULL);
    } else if (shared_ptr->tid > 0) {
        int ret = kill(shared_ptr->tid, 0); //~ send signal 0 to thread
        if (ret != 0) { //~ thread already died
            pthread_create(&id, NULL, thread_func, NULL);
        }
    }
    //~ unlock shared memory


沪ICP备19023445号-2号
友情链接