为什么新创建的线程不通过pthread_create()返回参数获取其tid但是pthread_self()

时间:2016-07-01 03:04:59

标签: linux thread-safety pthreads

这是从“Unix环境中的高级编程”创建线程的示例代码。至于线程创建,err = pthread_create(&ntid, NULL, thr_fn, NULL);新创建的线程可以使用ntid来打印自己的threadID,而不是调用pthread_self()吗?

#include "apue.h"
#include <pthread.h>

pthread_t ntid;

void
printids(const char *s)
{
    pid_t       pid;
    pthread_t   tid;

    pid = getpid();
    tid = pthread_self();
    printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid,
      (unsigned int)tid, (unsigned int)tid);
}

void *
thr_fn(void *arg)
{
    printids("new thread: ");      /* for the newly created thread,can it
                                    * print its own threadID just using ntid, 
                                    * instead of calling pthread_self() 
                                    */
    return((void *)0);
}

int
main(void)
{
    int     err;

    err = pthread_create(&ntid, NULL, thr_fn, NULL);
    if (err != 0)
        err_quit("can't create thread: %s\n", strerror(err));
    printids("main thread:");
    sleep(1);
    exit(0);
}

1 个答案:

答案 0 :(得分:1)

让我们检查规格:

http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_create.html

pthread_create(pthread_t *restrict thread,
  

成功完成后,pthread_create()会将创建的线程的ID存储在线程引用的位置。

     

调用线程可以通过pthread_create()函数的返回值获取创建的线程的ID,新创建的线程可以通过调用pthread_self()获取其ID。

问题是:ntid是调用函数的变量;即使它是全局的,从线程读取这个全局变量也不会扩展到两个或更多创建的线程。

其他问题是时间和执行顺序。在创建新线程后,pthread_create将线程ID写入ntid

  

成功完成后,pthread_create()会将创建的线程的ID存储在线程引用的位置。

因此,在没有同步的情况下从创建的线程中读取ntid是不安全的,新线程可能会在实际值写入全局之前读取。

因此,您应该使用pthread_selfhttp://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_self.html

  

pthread_self()函数应返回调用线程的线程ID。

     

pthread_self()函数提供类似于进程的getpid()函数的功能,其基本原理是相同的:创建调用不会为创建的线程提供线程ID。