Linux下获得线程ID

    对于Linux线程,也许大家并不陌生,而我们通常所说的线程是指基于POSIX标准的线程,而Linux下除了兼容POSIX标准,而且提供线程在内核级的支持。
    早在Linux kernel2.4之前,Linux的线程(LinuxThread)属于用户级,内核根本不知道线程的存在,为了得到内核的支持,2003年,Redhat公司(很了不起的一个公司)发布了NPTL(Native POSIX Thread Library),至今广泛使用。
    NPTL很优秀,对信号的处理是按照每进程的原则进行的;getpid() 会为所有的线程返回相同的进程 ID。例如,如果发送了 SIGSTOP 信号,那么整个进程都会停止;使用 LinuxThreads,只有接收到这个信号的线程才会停止。这样可以在基于 NPTL 的应用程序上更好地利用调试器,例如 GDB。
    额外话说多了,下面具体看看下面如何获得线程的ID吧!
   
    经常我们需要在程序一个线程中获得这个线程的id,有人会说,可以通过pthread_create函数传递参数传入,等主线程创建子线程成功,那么这个pid会自动赋值
#define TNUM 2
struct BN
{
    pthread_t pid;
    int N;
};

void *run(void *args)
{
    BN *recive = (BN *)args;
    cout << "pid: " << recive->pid << endl;
    return (void *)(recive->N);
}

int main(int c, char *v[])
{
    int i;
    int ret;
    char *result;
    pthread_t pid[TNUM];
    BN bn[TNUM];

    for (i = 0; i < TNUM; i ++)
     {
        bn[i].pid = pid[i];
        bn[i].N = mN;
        ret = pthread_create(&pid[i], NULL, run, &bn[i]);
    //...出错处理
    }
    return 0;
}
   难题是主线程去分配子线程id的时刻,run函数并不能很确切的知道,所以当读取recive->pid时,就会产生错误;
    正确的方法应该使用pthread_self()函数来获得POSIX的线程id,此函数调用内部进制直到pid分配完成。
    有人会问,获取进程id的函数不是getpid(),获取线程id的函数不是gettid()么?
这里与刚才前面所说的有些关系,目前gettid获得的pid是需要系统调用(syscall)的,这个syscall返回的pid不是上面所说的POSIX线程id,这个是内核的线程id,具体调用的方式如下:
pid_t pid = syscall(SYS_gettid);

pid_t pid = syscall(__NR_gettid);

//仅限于i386,如果是x86_64,则调用186
pid_t pid = syscall(224);
以往旧的方式syscallx的调用已经被废弃。
    看到这里,也许有人会问,pid_t和pthread_t可以相互转换么?一个是POSIX的线程、一个是内核的线程?如果你感兴趣在这方面研究的话,可以不妨试试,答案肯定是可以的。
    至此,你看完这篇文章,明白了linux线程id怎么获得了么?

Monthly Archives

Pages

Powered by Movable Type 7.7.2

About this Entry

This page contains a single entry by Cnangel published on October 27, 2009 2:56 PM.

Fedora 11无线网卡驱动安装 DELL E6400 was the previous entry in this blog.

TeX的字体的相关基础知识 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.