【问题标题】:pthread_t is initialised for thread it is defined in?pthread_t 是为它定义的线程初始化的?
【发布时间】:2013-11-10 13:33:40
【问题描述】:

我正在使用 pthread_t 打印出我在 C 中手动创建的线程的 pid。但是,我在创建新线程之前打印它(通过 ref 作为参数传递它)并打印不同的值(大概我的 main 函数正在执行的线程)。我本来希望它默认为 0 或未初始化。有任何想法吗? 谢谢,

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

struct thread_info {    /* Used as argument to thread_start() */
    pthread_t thread_id;/* ID returned by pthread_create() */
};

static void *thread_1_start(void *arg) {
    struct thread_info *myInfo = arg;
    printf("Started thread id: %d\n", myInfo->thread_id);
    pthread_exit(0);
}

int main() {
    struct thread_info tinfo;

    int s;
    printf("Main thread id: %d\n", tinfo.thread_id);
    s = pthread_create(&tinfo.thread_id,
        NULL, // was address of attr, error as this was not initialised.
        &thread_1_start,
        &tinfo);
    pthread_join(tinfo.thread_id,NULL);
}

实际输出:

Main thread id: 244580352
Started thread id: 245325824

预期输出:

Main thread id: // 0 or undefined
Started thread id: 245325824

【问题讨论】:

  • 还可以查看this 以更好地了解线程 ID。

标签: c multithreading pthreads pid


【解决方案1】:

问题是你没有初始化tinfo 结构。

在局部变量(相对于全局/堆变量)中,值在 C 编程语言中初始化。

所以,如果你这样做:

int c;
printf("%d", c);

你不应该期望一个连贯的值,因为它取决于那一刻内存位置上的内容。

您需要初始化tinfo 变量。使用memset 或显式分配tinfo.thread_id = 0

【讨论】:

  • 我不确定这是怎么回事,就好像它是“恰好在那个空间的内存中发生的事情”,这两个 PID 是否一直如此接近彼此?例如,主线程 id:170115072 开始线程 id:170860544 并运行 2 主线程 id:221585408 开始线程 id:222330880
【解决方案2】:

没有线程特定的逻辑来初始化tinfo;它只是一个常规的 C 结构。它将具有初始化时该内存地址中的任何数据。您需要显式初始化它。

您可以通过以下方式将值初始化为零:

struct thread_info tinfo = { 0 };

【讨论】:

  • 您提供线程 id,以后的会从那里增加。发生的事情是您提供了一个初始化值作为线程 ID,并用于创建下一个。例如,将值设置为1234,看看下一个会变成什么。
  • 所以我添加了'tinfo.thread_id=1234;',然后重新运行。输出是: Main thread id: 1234 Started thread id: 215781376 你不是说启动线程 id: 会少很多吗? 1234 + 一个小 pid?
  • 我可能对小偏移量有误,但是您的第一个案例可以重复吗?比如说 10 次处决,你得到的值是否相互接近?
  • 尝试了 10 次处决,所有数字与上述差异相似 - 非常接近。
【解决方案3】:

声明struct thread_info tinfo; global,看看会发生什么。

【讨论】:

    【解决方案4】:

    您需要了解许多重要的事情。

    首先,pthread_t 是不透明的。您无法使用 printf 可靠地打印它,因为 POSIX 标准中没有任何地方将 pthread_t 指定为 beinban into、struct 或其他任何内容。根据定义,您无法打印它并获得有意义的输出。

    其次,如果一个线程需要知道它的 pthread_t ID,它可以调用 pthread_self()。你不需要告诉线程它的 ID 是什么,就像你试图做的那样。

    但没关系!您描述的打印输出接近您期望的条件是因为您在线程打印输出和 pthread_create 之间存在竞争,将 pthread_t 分配给 thread_info.thread_id,并且由于 pthread_t 实际上是 Linux 上的整数类型(所以它们很可能是按顺序分配的,而你只是得到一个旧值)。

    【讨论】:

    • re: second - 这里的重点是我传递对 pthread_t 的引用以供其内部使用并且我不必关心此 pthread_t 的内容或使用它?那为什么不把它放在引擎盖下呢?为什么我在运行 pthread_create() 时要传递对 pthread_t 的引用?
    • @SamHeather,您这样做是为了让调用 pthread_create() 的线程可以拥有启动线程的 ID。这允许它稍后调用像 pthread_join() 这样的函数。如果程序中不需要这样做(也许它永远不需要退出!),您可以丢弃 pthread_create() 返回的值。通常,您会将 pthread_create 返回的 pthread_t 存储在某个局部变量(不与线程共享)中,以便在程序退出之前在 pthread_join() 中使用。
    猜你喜欢
    • 2014-12-20
    • 1970-01-01
    • 2021-06-17
    • 2012-05-26
    • 2023-03-28
    • 2012-05-16
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    相关资源
    最近更新 更多