传递给 pthread_create 的例程何时开始?

Cos*_*una 1 c posix pthreads

给出以下代码

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

Ant*_*ala 5

嗯,实际上有两个问题:

\n\n
    \n
  • 哪个线程将首先执行
  • \n
  • 在新线程启动之前,线程 id 是否会被保存。
  • \n
\n\n

这个答案涉及Linux,因为我没有任何其他可用的平台。第一个问题的答案可以在手册中找到:

\n\n
\n

除非采用实时调度策略,否则在调用之后 pthread_create(),无法确定调用者接下来执行哪个线程 xe2x80x94 或新线程 xe2x80x94。

\n
\n\n

因此很明显,在您的情况下,不确定哪个线程实际上将首先运行。现在,另一个问题是如何pthread_create实现 - 是否可以以某种方式创建一个休眠线程,首先存储其 id,然后再启动它?

\n\n

好吧,Linux 使用系统调用创建新线程clone

\n\n
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\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,线程 id 似乎是用调用中的指针存储的clone,但很明显,它child_tidptr并不引用的地址 tid,就好像我打印它一样,地址是不同的;这是pthread库中的一些内部变量;并tid会在系统调用在父线程中返回后更新。clone

\n\n

事实上,pthread_self如下所示:

\n\n
\n

返回的线程 ID 与pthread_self()调用返回的内核线程 ID 不同gettid(2)

\n
\n\n

这证实了内核线程 id 与pthread_ts不同

\n\n

因此,除了POSIX 规范不支持这一点之外,实际上在 Linux 平台上也没有这样的保证 -返回后tid需要在父线程clone中设置,否则父线程不会立即知道该线程子进程的 id - 但这也意味着如果子进程是返回后第一个执行的,那么线程 id 可能还没有设置在那里。

\n