繁体   English   中英

传递给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,但是我只是想知道例程何时运行。

好吧,实际上有两个问题:

  • 哪个线程将首先执行
  • 将在新线程启动之前保存线程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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM