繁体   English   中英

pthread_create之间的循环ID是否重复?

[英]Duplicated thread ID in pthread_create between loop?

我有一个循环,循环的每次迭代都会使用pthread_create创建5个线程。 我注意到线程ID的重复不在同一循环内,而是在循环之间。 这是正确的吗,因为我期望所有线程ID都是唯一的?

这是示例代码,

#include <pthread.h>
#define NTHREADS1 5
void maintest()
{
    loopCreate();

}
void loopCreate()
{

 for(int index=0; index<2; index++)
 {
    int i;
    int j;
    pthread_t thread_id[NTHREADS1];
    for(i=0; i < NTHREADS1; i++)
   {
      pthread_create( &thread_id[i], NULL, thread_function, NULL );
      cout<<"threadcnt="<<i<<"; "<<"thread_id=" << thread_id[i] << endl;
   }

    for(j=0; j < NTHREADS1; j++)
   {
      pthread_join( thread_id[j], NULL); 
   }
 }  
}

void *thread_function(void *dummyPtr)
{
  int j;
  int jcounter;
  jcounter =0;
  pthread_t threadId;
  threadId = pthread_self();
  cout<<"Thread_number="<<threadId<<endl;

  return NULL;
}

这是输出跟踪,如您所见,循环1和循环2之间存在重复的线程ID

//Loop 1
threadcnt=0; thread_id=2061794160
Thread_number=2061794160
threadcnt=1; thread_id=2264922992
Thread_number=2264922992
threadcnt=2; thread_id=2162469744
Thread_number=2162469744
threadcnt=3; thread_id=2128911216
Thread_number=2128911216
Thread_number=2095352688
threadcnt=4; thread_id=2095352688

//Loop 2
threadcnt=0; thread_id=2095352688
Thread_number=2095352688
threadcnt=1; thread_id=2264922992
Thread_number=2264922992
threadcnt=2; thread_id=2162469744
Thread_number=2162469744
threadcnt=3; thread_id=2128911216
Thread_number=2128911216
Thread_number=2061794160
threadcnt=4; thread_id=2061794160

编辑:有关pthread_t结构的更深入的讨论,请参阅@Alexander Schwartz的答案。

您将在每次迭代结束时加入线程。 https://linux.die.net/man/3/pthread_self可以看到:

终止的线程已加入或分离的线程已终止后,可以重新使用线程ID。

因此,操作系统无需重用已终止(在您已连接的情况下)线程的ID。

此外来自https://linux.die.net/man/7/pthreads

进程中每个线程都有一个唯一的线程标识符 (存储在pthread_t类型中)。 该标识符返回给pthread_create(3)的调用者,线程可以使用pthread_self(3)获得其自己的线程标识符。

因此,可以确保仅在进程的运行线程集上具有唯一的ID。

没有错误的代码不可能告诉pthread_t是否被重用。 您的代码有一个错误:

  cout<<"threadcnt="<<i<<"; "<<"thread_id=" << thread_id[i] << endl;

什么也没有指定pthread_t的打印值。 它可能包括也可能不包括pthread_t的整个值。 每个人都可以打印为零。 您无法假设它意味着任何东西。

此代码甚至可能崩溃。 输出例程可以尝试访问pthread_t中未映射到内存的字节。 此代码的行为是完全未定义的。 在您的平台上, pthread_t行为可能类似于char *并且此代码可能会尝试取消引用它,但它可能不会指向任何有效的对象。 谁知道? 该标准使pthread_t成为完全不透明的类型,仅具有非常有限的一组定义操作。

该标准明确允许pthread_tstruct 因此,该标准甚至不需要此代码进行编译。 期望有意义的值是不合理的。

您可能认为可以通过比较pthread_t的相等性(而不是打印它们)来做到这一点。 但是你不能。 比较pthread_t的相等性的唯一允许方法是与pthread_equal进行比较,但是文档说:“ 如果t1或t2不是有效的线程ID,则行为未定义。 ”并且由于线程已终止并已加入,因此其ID为no有效期更长。

从根本上讲,不可能复制线程ID,因为两个线程ID的生存期没有任何重叠,并且线程ID在生存期之后都没有有意义的值。 线程ID只是对该线程的不透明引用,而该线程尚未连接,终止和分离。 没有数值。 内存的实际字节可能包含无关的字节,间接引用或其他任何内容。 pthreads标准明确表示您不能以这种方式操作线程ID。

如果您需要具有不同语义的线程ID,则有很多方法可以获取一种。 但这不是 pthread_t

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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