[英]pthreads in C: How can I stop the threads from interfering with each other?
我是使用 pthreads 的新手。 我想創建一個程序,其中六個不同的線程將每個 output 一個不同的數字。 線程可以按任何順序運行,但是,每個線程只能運行一次。
因此,可能的 output 將是:
Thread: 5
Thread: 2
Thread: 3
Thread: 6
Thread: 1
Thread: 4
或者它可以是任何其他順序。
#include<stdio.h>
#include<pthread.h>
void *apples(void *void_apple_num){
int *thread_num = (int *) void_apple_num;
printf("Thread: %d\n", *thread_num);
return NULL;
}
int main(){
pthread_t threads[6];
int apple_num;
for(apple_num=0; apple_num<6; apple_num++){
pthread_create(&threads[apple_num], NULL, apples, &apple_num);
}
for(apple_num=0; apple_num<6; apple_num++){
pthread_join(threads[apple_num], NULL);
}
return 0;
}
當我運行程序時,我遇到了線程相互干擾的問題。 我不確定某些線程是否運行了兩次? 但是,我認為問題在於某些線程正在使用來自不同線程的apple_num
指針。
這是我得到的兩個示例輸出:
Output 1:
Thread: 5
Thread: 0
Thread: 1
Thread: 1
Thread: 2
Thread: 2
Output 2:
Thread: 1
Thread: 4
Thread: 4
Thread: 5
Thread: 1
Thread: 1
我不完全明白是什么導致了這個問題。 我聽說線程有時可以共享變量? 我不知道我是否應該使用互斥鎖以某種方式讓線程一次運行一個。
如何編輯我的代碼來解決這個問題?
如果其他人問過類似的問題,請引導我回答他們的問題。 我在研究時找不到任何東西。
您的每個線程都有一個指向同一個局部變量apple_num
的指針,該變量正在由主線程在循環中更改。 由於線程是異步啟動的,因此主線程中的局部變量apple_num
的值在任何其他線程看來都是不確定的。
您需要將該變量的副本傳遞給每個線程。
一種解決方法是將int
轉換為void*
並返回:
void *apples(void* apple_num){
int thread_num = (int)void_apple_num;
...
pthread_create(&threads[apple_num], NULL, apples, (void*)apple_num);
正如他們在評論中提到的那樣, intptr_t
和uintptr_t
(來自<stdint.h>
)可能更適合無損失的往返,例如uintptr_t
-> void*
-> uintptr_t
。 但是 C 標准不需要任何整數來往返void*
並返回,它只需要void*
-> intptr_t
並返回。
在更現實的場景中,您可能希望將多個 integer 傳遞給線程,即struct
。 這就是線程啟動 function 以接收單個void*
參數的基本原理 - 它可以指向任何數據類型的 object(POSIX 需要void*
也能夠存儲 ZC1C425268E18385D14ZF5074 指針)。
將結構傳遞給線程的示例(不依賴於實現定義的整數到void*
和返回的轉換):
struct ThreadArgs {
int thread_num;
// More data members, as needed.
};
void* apples(void* arg){
struct ThreadArgs* a = arg;
printf("Thread: %d\n", a->thread_num);
free(arg);
return NULL;
}
int main() {
pthread_t threads[6];
struct ThreadArgs* a;
int apple_num;
for(apple_num=0; apple_num<6; apple_num++){
a = malloc(sizeof *a);
a->thread_num = apple_num;
pthread_create(&threads[apple_num], NULL, apples, a);
}
for(apple_num=0; apple_num<6; apple_num++)
pthread_join(threads[apple_num], NULL);
return 0;
}
請注意,您不必在堆 ( malloc
) 上分配線程 arguments 結構。 如果您將自動變量(在堆棧上)傳遞給線程,則必須確保該變量未更改並且在線程訪問它時仍然存在。 從堆中分配線程 arguments 結構是最安全的,並且以malloc
/ free
調用為代價解決了這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.