2017-06-23 42 views
0

考虑下面的代码例程何时传递给pthread_create开始?

#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,但我只是想知道例程运行的时间。

+0

“在pthread_create()'的调用之后,”例程何时传递给pthread_create start?“?你的问题不清楚。 “例行公事能够得到正确的结论吗?”你什么意思 ? – Stargateur

+1

您将'&tid'作为'pthread_create'(pthread_create'应该存储新线程ID的地方)的第一个参数和'pthread_create'的第四个参数(要传入'pt_routine'的参数) 。它*听起来像是在询问'pt_routine'是否可以运行并在'pthread_create'实际存储线程的ID之前取消引用'arg'。那是对的吗? – Wyzard

回答

3

嗯,其实有2个问题:

  • 哪个线程将首先
  • 执行将线程ID被保存在新线程开始前

这个答案涉及Linux,因为我没有任何其他平台可用。在回答第一个问题,可以发现in the manuals

除非实时正在使用 调度策略,在通话后 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没有按” t参考地址tid,好像我打印出来的,地址是不同的;这是pthread库中的一些内部变量;和tid将更新clone系统调用返回在父线程中。

事实上,pthread_self说以下内容:

通过pthread_self()返回的线程ID是不一样的东西 如通过调用返回到gettid(2)内核线程ID。

这证实了内核线程ID是不同于pthread_t小号

因此,除了这不是由POSIX spec支持,但在实践中是在Linux平台上没有这样的保证 - 在tid会需要设置父线程clone返回,否则不会立即知道子的线程ID - 但这也意味着如果子是第一个在返回后执行,那么线程ID可能尚未设置。

+0

非常感谢!非常清楚,乐于助人! –

2

pt_thread()将在调用pthread_create()之后的某个任意点开始执行 - 包括在pthread_create()返回到调用代码之前它可能会开始运行。并且不保证pthread_create()实现将在线程开始执行之前更新tid变量。

因此,您的代码中没有任何内容可确保pt_routine()正确读取tid值。您需要使用某种同步来确保在没有数据竞争的情况下正确执行。或者你可以通过线索电话pthread_self()

the POSIX spec for pthread_create()“应用程序使用”部分:

有上实现了创建的线程的ID提供新创建的线程开始执行之前没有要求。调用线程可以通过在pthread_create()函数的返回值获得所创建的线程的ID,和新创建的线程可以通过电话获得其ID来pthread_self

+0

另一个[quote](http://man7.org/linux/man-pages/man3/pthread_create.3.html)来自linux手册页:“请参阅pthread_self(3)以获取有关* thread中返回的线程ID的更多信息通过pthread_create()。除非采用实时调度策略,否则在调用pthread_create()之后,不确定哪个线程(即调用者或新线程)将接下来执行。 – Stargateur

相关问题