简体   繁体   English

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

[英]Duplicated thread ID in pthread_create between loop?

I have a loop and each iteration of the loop will create 5 threads with pthread_create. 我有一个循环,循环的每次迭代都会使用pthread_create创建5个线程。 I noticed there are duplicates of thread IDs not within the same loop, but between loops. 我注意到线程ID的重复不在同一循环内,而是在循环之间。 Is this correct as i'm expecting all the thread IDs should be unique? 这是正确的吗,因为我期望所有线程ID都是唯一的?

Here are the sample code, 这是示例代码,

#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;
}

And here is output trace and as you can see, there are duplicate thread IDs between loop 1 and loop 2 这是输出跟踪,如您所见,循环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

Edit: for a more in-depth discussion on the structure of pthread_t please see @Alexander Schwartz's answer. 编辑:有关pthread_t结构的更深入的讨论,请参阅@Alexander Schwartz的答案。

You are joining the threads at the end of each iteration. 您将在每次迭代结束时加入线程。 From https://linux.die.net/man/3/pthread_self we can see: https://linux.die.net/man/3/pthread_self可以看到:

[...] A thread ID may be reused after a terminated thread has been joined, or a detached thread has terminated. 终止的线程已加入或分离的线程已终止后,可以重新使用线程ID。

So the OS is free of reusing ids of terminated (in your case joined) threads. 因此,操作系统无需重用已终止(在您已连接的情况下)线程的ID。

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

Each of the threads in a process has a unique thread identifier (stored in the type pthread_t). 进程中每个线程都有一个唯一的线程标识符 (存储在pthread_t类型中)。 This identifier is returned to the caller of pthread_create(3), and a thread can obtain its own thread identifier using pthread_self(3). 该标识符返回给pthread_create(3)的调用者,线程可以使用pthread_self(3)获得其自己的线程标识符。

So you are guaranteed to have uniqueness of IDs only on the set of running threads of a process. 因此,可以确保仅在进程的运行线程集上具有唯一的ID。

There is no way bug free code could ever tell if a pthread_t is reused. 没有错误的代码不可能告诉pthread_t是否被重用。 Your code has a bug: 您的代码有一个错误:

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

Nothing specifies what the printed value of a pthread_t should be. 什么也没有指定pthread_t的打印值。 It may or may not include the entire value of the pthread_t . 它可能包括也可能不包括pthread_t的整个值。 Every one could print as zero. 每个人都可以打印为零。 You cannot assume it means anything at all. 您无法假设它意味着任何东西。

This code could even crash. 此代码甚至可能崩溃。 The output routine could try to access bytes in the pthread_t that are not mapped into memory. 输出例程可以尝试访问pthread_t中未映射到内存的字节。 The behavior of this code is entirely undefined. 此代码的行为是完全未定义的。 On your platform, pthread_t might behave like char * and this code might attempt to dereference it, but it may not point to any valid object. 在您的平台上, pthread_t行为可能类似于char *并且此代码可能会尝试取消引用它,但它可能不会指向任何有效的对象。 Who knows? 谁知道? The standard makes pthread_t an entirely opaque type with only a very limited set of defined operations. 该标准使pthread_t成为完全不透明的类型,仅具有非常有限的一组定义操作。

The standard explicitly permits a pthread_t to be a struct . 该标准明确允许pthread_tstruct So the standard doesn't even require this code to compile. 因此,该标准甚至不需要此代码进行编译。 It is unreasonable to expect a meaningful value. 期望有意义的值是不合理的。

You might think that you can do it by comparing the pthread_t s for equality rather than printing them. 您可能认为可以通过比较pthread_t的相等性(而不是打印它们)来做到这一点。 But you cannot. 但是你不能。 The only permitted way to compare pthread_t s for equality is with pthread_equal but the documentation says, " If either t1 or t2 are not valid thread IDs, the behavior is undefined. " and since the thread has terminated and been joined, it's ID is no longer valid. 比较pthread_t的相等性的唯一允许方法是与pthread_equal进行比较,但是文档说:“ 如果t1或t2不是有效的线程ID,则行为未定义。 ”并且由于线程已终止并已加入,因此其ID为no有效期更长。

It is literally impossible for a thread ID to be duplicated because the two thread IDs do not have any overlap in their lifetime and there is no meaningful value to the thread ID that persists beyond its lifetime. 从根本上讲,不可能复制线程ID,因为两个线程ID的生存期没有任何重叠,并且线程ID在生存期之后都没有有意义的值。 A thread ID is just an opaque reference to a thread while that thread has not been joined or terminated and detached. 线程ID只是对该线程的不透明引用,而该线程尚未连接,终止和分离。 It has no numerical value. 没有数值。 The actual bytes of memory may contain extraneous bytes, indirect references, or anything else. 内存的实际字节可能包含无关的字节,间接引用或其他任何内容。 The pthreads standard explicitly says you may not manipulate a thread ID in this way. pthreads标准明确表示您不能以这种方式操作线程ID。

If you need a thread ID that has different semantics, there are lots of ways you can get one. 如果您需要具有不同语义的线程ID,则有很多方法可以获取一种。 But that would not be pthread_t . 但这不是 pthread_t

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

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