2017-06-23 44 views
0

考慮下面的代碼例程何時傳遞給pthread_create開始?

#include <pthread.h> 

void *pt_routine(void *arg) 
{ 
    pthread_t *tid; 
    tid = (pthread_t *) arg; 
    /* do something with tid , say printf?*/ 
    /* 
    printf("The thread ID is %lu\n", *tid); 
    */ 
    return NULL; 
} 

int main(int argc, char **argv) 
{ 
    int rc; 
    pthread_t tid; 
    rc = pthread_create(&tid, NULL, pt_routine, &tid); 
    if (rc) 
    { 
     return 1; 
    } 
    printf("The new thread is %lu\n", tid); 
    pthread_join(tid, NULL); 
    return 0; 
} 

例行總能得到正確的tid

當然,我可以使用pthread來獲取自我ID,但我只是想知道例程運行的時間。

+0

「在pthread_create()'的調用之後,」例程何時傳遞給pthread_create start?「?你的問題不清楚。 「例行公事能夠得到正確的結論嗎?」你什麼意思 ? – Stargateur

+1

您將'&tid'作爲'pthread_create'(pthread_create'應該存儲新線程ID的地方)的第一個參數和'pthread_create'的第四個參數(要傳入'pt_routine'的參數) 。它*聽起來像是在詢問'pt_routine'是否可以運行並在'pthread_create'實際存儲線程的ID之前取消引用'arg'。那是對的嗎? – Wyzard

回答

3

嗯,其實有2個問題:

  • 哪個線程將首先
  • 執行將線程ID被保存在新線程開始前

這個答案涉及Linux,因爲我沒有任何其他平臺可用。在回答第一個問題,可以發現in the manuals

除非實時正在使用 調度策略,在通話後 pthread_create(),它是不確定的,其線程來電或 新線程意志下一步執行。

因此很明顯,在你的情況下,它是不確定哪個線程實際上首先運行。現在,另一個問題是如何實現pthread_create - 如果它能以某種方式創建一個休眠線程,首先存儲它的id,然後再啓動它?

那麼,Linux的創建使用clone系統調用新的線程:

clone(child_stack=0x7f7b35031ff0, 
     flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM 
      |CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, 
     parent_tidptr=0x7f7b350329d0, 
     tls=0x7f7b35032700, 
     child_tidptr=0x7f7b350329d0) = 24009 

現在看來該線程ID存儲從clone調用一個指針,但它似乎很清楚,child_tidptr沒有按」 t參考地址tid,好像我打印出來的,地址是不同的;這是pthread庫中的一些內部變量;和tid將更新clone系統調用返回在父線程中。

事實上,pthread_self說以下內容:

通過pthread_self()返回的線程ID是不一樣的東西 如通過調用返回到gettid(2)內核線程ID。

這證實了內核線程ID是不同於pthread_t小號

因此,除了這不是由POSIX spec支持,但在實踐中是在Linux平臺上沒有這樣的保證 - 在tid會需要設置父線程clone返回,否則不會立即知道子的線程ID - 但這也意味着如果子是第一個在返回後執行,那麼線程ID可能尚未設置。

+0

非常感謝!非常清楚,樂於助人! –

2

pt_thread()將在調用pthread_create()之後的某個任意點開始執行 - 包括在pthread_create()返回到調用代碼之前它可能會開始運行。並且不保證pthread_create()實現將在線程開始執行之前更新tid變量。

因此,您的代碼中沒有任何內容可確保pt_routine()正確讀取tid值。您需要使用某種同步來確保在沒有數據競爭的情況下正確執行。或者你可以通過線索電話pthread_self()

the POSIX spec for pthread_create()「應用程序使用」部分:

有上實現了創建的線程的ID提供新創建的線程開始執行之前沒有要求。調用線程可以通過在pthread_create()函數的返回值獲得所創建的線程的ID,和新創建的線程可以通過電話獲得其ID來pthread_self

+0

另一個[quote](http://man7.org/linux/man-pages/man3/pthread_create.3.html)來自linux手冊頁:「請參閱pthread_self(3)以獲取有關* thread中返回的線程ID的更多信息通過pthread_create()。除非採用實時調度策略,否則在調用pthread_create()之後,不確定哪個線程(即調用者或新線程)將接下來執行。 – Stargateur

相關問題