![](/img/trans.png)
[英]What is the type of "start_routine" passed to pthread_create
[英]When does the routine passed to pthread_create start?
给出以下代码
#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;
}
常规总能得到正确的tid
?
当然,我可以使用pthread来获取自身ID,但是我只是想知道例程何时运行。
好吧,实际上有两个问题:
这个答案与Linux有关,因为我没有其他可用的平台。 第一个问题的答案可以在手册中找到:
除非采用实时调度策略,否则在调用
pthread_create()
,不确定哪个线程(调用者或新线程)接下来将执行。
因此很明显,在您的情况下,不确定哪个线程将首先运行。 现在,另一个问题是如何实现pthread_create
如果它可以以某种方式创建一个休眠线程,先存储其ID,然后再启动它?
好吧,Linux使用clone
系统调用创建了新线程:
clone(child_stack=0x7f7b35031ff0,
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM
|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,
parent_tidptr=0x7f7b350329d0,
tls=0x7f7b35032700,
child_tidptr=0x7f7b350329d0) = 24009
现在,似乎线程ID是与clone
调用中的指针一起存储的,但显然child_tidptr
并没有引用tid
的地址 ,就像我打印它一样,该地址是不同的。 这是pthread
库中的一些内部变量; clone
系统调用在父线程中返回后 , tid
将被更新。
实际上, pthread_self
表示以下内容:
pthread_self()
返回的线程ID与对gettid(2)
的调用返回的内核线程ID不同。
这确认内核线程ID与pthread_t
不同
因此,除了POSIX规范不支持此功能外,实际上在Linux平台上也没有这样的保证- clone
返回后,需要在父线程中设置tid
,否则父级不会立即知道子代的线程ID-但这也意味着,如果子代是返回后第一个执行的子代,则可能尚未在此处设置线程ID。
pt_thread()
将在调用pthread_create()
之后的任意点开始执行-包括可能在pthread_create()
返回调用代码之前开始运行。 并且不能保证pthread_create()
实现将在线程开始执行之前更新tid
变量。
因此,您的代码中没有什么可以确保pt_routine()
可以正确读取tid
值。 您将需要使用某种同步来确保在没有数据争用的情况下正确进行。 或者,您可以使用线程调用pthread_self()
。
请参阅POSIX规范的“应用程序使用情况”部分中的pthread_create()
:
在实现上,不需要在新创建的线程开始执行之前可用已创建线程的ID。 调用线程可以通过pthread_create()函数的返回值获取创建的线程的ID,而新创建的线程可以通过调用
pthread_self
来获取其ID。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.