[英]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_t
為struct
。 因此,該標准甚至不需要此代碼進行編譯。 期望有意義的值是不合理的。
您可能認為可以通過比較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.