pthread_t什么时候为0?

时间:2019-07-09 07:57:27

标签: pthreads

我在RHEL 7.2中使用pthread_create()创建了线程。 pthread_create返回0,但是* thread(第一个参数)为0。

您知道线程ID为0的原因吗?

... condition= :paramName

输出: 线程已启动:0

3 个答案:

答案 0 :(得分:1)

  

我在RHEL 7.2中使用pthread_create()创建了线程。 pthread_create   返回0,但* thread(第一个参数)为0。

     

您知道线程ID为0的原因吗?

暂时假设它真的为 0,那又是什么呢?前提是pthread_t是算术类型,当前版本的POSIX并未指定该算术类型,但是如果这样,则0是其有效值。对于特定的线程标识符值,没有任何文献记载的意义,特别是,没有理由认为,如果线程是pthread_t类型的有效值,则不应为该线程分配0作为其标识符。

由于您还提到了pthread_create的返回值,所以我想您可能认为它与线程ID之间存在某种关系。没有记录这样的关系,只是在返回值恰好为0的情况下,pthread_create()返回之后才定义线程ID的值。

但这确实指向您的代码中的问题,@ErikAlapää首先指出:pthread_create()在函数组中,这些函数在失败时直接返回错误号, 不是 在失败时返回-1的组,希望您向errno咨询错误号。错误号为正,因此无法依靠您的条件if(0 > nThread)来检测pthread_create是否失败。您应该针对0:

if (0 != nThread) {
    printf("failed");
} else {
    printf("thread started: %lu", (unsigned long) thread[0]);
}

还要注意格式更改并在第二个printf()调用中强制转换。您需要第二个参数具有与格式设置指令完全相同的类型(以前为%ld,现在为%lu),即unsigned long int。只要pthread_t是算术或指针类型,强制转换都是有效的,并且在实践中,可以依赖编译器拒绝代码(如果是其他类型),例如结构类型。鉴于必须使用强制类型转换(但可能不足以获取已知类型),因此 unsigned 类型更为安全,因为如果原始值超出了范围,则转换将定义行为。目标类型。如果您的类型不匹配(如您在原始代码中可能遇到的那样),则该行为是不确定的,并且在这种UB的无数种可能的表现中,更有可能的是尽管thread[0]仍打印了“ 0”非零。

话虽如此,即使您的原始代码有缺陷,我也不会重现您的问题。我倾向于怀疑您的pthread_create调用失败,可能是因为您使用的是没有线程支持而构建的C库,或者是链接了伪pthread例程而不是函数式例程。确保在构建时为pthreads程序提供正确的选项。例如,如果要使用gcc进行编译,则需要提供-pthread选项。如果您有单独的编译和链接步骤,请对两者都使用该选项。

答案 1 :(得分:0)

请尝试检查返回值是否恰好为零。仅当返回值为0时,线程创建成功。

errno联机帮助页上显示​​“有效错误号均为正数”。例如,在Linux上,errno错误号似乎介于0和200之间。

另外,使用例如,打印与您得到的errno错误号相对应的消息。 perror()。

答案 2 :(得分:0)

根据POSIX,pthread_t类型是不透明的。它可以是任何类型。特别是,不需要是算术类型(指针或整数)。符合要求的POSIX线程实现可以将struct的{​​{1}}使用。

如果pthread_t恰好是整数类型,则不禁止它为零。它可能是某个线程在某个数组中的索引,因此第一个线程的位置为零。

毕竟我们对标准输入文件描述符为零并不感到惊讶。