簡體   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