簡體   English   中英

為什么我創建的線程沒有按順序打印?

[英]Why are my threads I created not printed in order?

我有這個程序:

void *func(void *arg) {
    pthread_mutex_lock(&mutex);
    int *id = (int *)arg;

    printf("My ID is %d\n" , *id);
    pthread_mutex_unlock(&mutex);
}

int main() {
    int i;
    pthread_t tid[3];

    // Let us create three threads
    for (i = 0; i < 3; i++) {
        pthread_create(&tid[i], NULL, func, (void *)&i);
    }

    for (i = 0; i < 3; i++) {
        pthread_join(tid[i], NULL);
    }

    pthread_exit(NULL);
    return 0;
}

我希望它能輸出以下內容:

My ID is 0
My ID is 1
My ID is 2

但是我得到的是隨機輸出,例如:

My ID is 0
My ID is 0
My ID is 2

由於我已經添加了互斥鎖,所以我認為這可以解決問題。 我還做錯了什么? 這與種族狀況有關嗎?

在此, id指向所有線程的main中相同的變量i

int *id = (int *)arg;

printf("My ID is %d\n" , *id);

但是變量i經常被線程后面的main的兩個for -loops更新。 因此,在線程到達printf的點之前, i的值以及*id的值可能已經更改。

有幾種解決方法。 最佳方法取決於用例:

  1. 在修改線程i或使其超出范圍之前,先在main等待線程發出信號,表明它已復制*id
  2. 聲明並初始化一個數組int thread_id[] ,然后像下面那樣創建線程: pthread_create(&tid[i], NULL, func, &thread_id[i]);
  3. malloc一些內存並使用i的副本對其進行初始化:

     int *thread_id = malloc(sizeof(*thread_id)); *thread_id = i pthread_create(&tid[i], NULL, func, thread_id); 

    只是不要忘記在使用完線程后將其free到線程中。 或者在main線程中,如果線程無法啟動。

  4. 如果i適合一個void *可以將其內容直接作為參數傳遞給線程。 為了確保它合適,可以將其聲明為intptr_t而不是int (我們基本上濫用了指針不過是魔術整數這一事實):

     void *func(void *arg) { pthread_mutex_lock(&mutex); // Here we interpret a pointer value as an integer value intptr_t id = (intptr_t )arg; printf("My ID is %d\\n" , (int)id); pthread_mutex_unlock(&mutex); } int main() { intptr_t i; pthread_t tid[3]; // Let us create three threads for (i = 0; i < 3; i++) { // Here we squeeze the integer value of `i` into something that is // supposed to hold a pointer pthread_create(&tid[i], NULL, func, (void *)i); } for (i = 0; i < 3; i++) { pthread_join(tid[i], NULL); } // This does not belong here !! // pthread_exit(NULL); return 0; } 

不,不涉及比賽條件。 (my b)i上可能存在競爭狀況,因為所有線程都訪問它。 每個線程都以指向i的指針開始。 但是,主要問題是,不能保證在我按您期望的順序保存您期望的值時,線程將啟動並運行關鍵部分。

我假設您全局聲明了變量mutex ,並在某處調用pthread_mutex_init()進行了初始化。

互斥體很棒,一次允許一個線程訪問關鍵的代碼部分。 因此,您編寫的代碼創建了所有三個線程以並行運行,但一次只允許一個線程運行以下代碼。

int *id = (int *)arg;

printf("My ID is %d\n" , *id);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM