给出以下代码
#include <pthread.h>
void *pt_routine(void *arg)
{
pthread_t *tid;
tid = (pthread_t *) arg;
/* do something with tid , say printf?*/
/*
printf("The thread ID is %lu\n", *tid);
*/
return NULL;
}
int main(int argc, char **argv)
{
int rc;
pthread_t tid;
rc = pthread_create(&tid, NULL, pt_routine, &tid);
if (rc)
{
return 1;
}
printf("The new thread is %lu\n", tid);
pthread_join(tid, NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例行公事能永远正确吗tid?
当然,我可以使用 pthread 来获取自身 ID,但我只是想知道例程何时运行。
嗯,实际上有两个问题:
\n\n这个答案涉及Linux,因为我没有任何其他可用的平台。第一个问题的答案可以在手册中找到:
\n\n\n\n\n除非采用实时调度策略,否则在调用之后
\npthread_create(),无法确定调用者接下来执行哪个线程 xe2x80x94 或新线程 xe2x80x94。
因此很明显,在您的情况下,不确定哪个线程实际上将首先运行。现在,另一个问题是如何pthread_create实现 - 是否可以以某种方式创建一个休眠线程,首先存储其 id,然后再启动它?
好吧,Linux 使用系统调用创建新线程clone:
clone(child_stack=0x7f7b35031ff0, \n flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM\n |CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,\n parent_tidptr=0x7f7b350329d0,\n tls=0x7f7b35032700,\n child_tidptr=0x7f7b350329d0) = 24009\nRun Code Online (Sandbox Code Playgroud)\n\n现在,线程 id 似乎是用调用中的指针存储的clone,但很明显,它child_tidptr并不引用的地址 tid,就好像我打印它一样,地址是不同的;这是pthread库中的一些内部变量;并tid会在系统调用在父线程中返回后更新。clone
事实上,pthread_self如下所示:
\n\n\n返回的线程 ID 与
\npthread_self()调用返回的内核线程 ID 不同gettid(2)。
这证实了内核线程 id 与pthread_ts不同
因此,除了POSIX 规范不支持这一点之外,实际上在 Linux 平台上也没有这样的保证 -返回后tid需要在父线程clone中设置,否则父线程不会立即知道该线程子进程的 id - 但这也意味着如果子进程是返回后第一个执行的,那么线程 id 可能还没有设置在那里。