[英]Unexpected results printing array of int pointers in C
我有一個簡單的C程序,該程序使用不同數量的pthread來查找前N個素數,並將發現的素數添加到數組中。 數組作為arg傳遞給每個線程,每個線程在關鍵部分執行幾乎所有代碼。 我對素數檢查沒有任何問題,並且可以找到質數和result_number變量的屏幕打印。 但是,當找到N個質數並打印了數組時,我發現(大約)每隔第二次執行該程序,就會有一些(從1到5可變)早期質數數組元素(通常限於<17)以極大或負數打印出來,大多數素數打印效果很好。 下面只有線程函數的代碼(不是checkPrime或main),因為其他所有東西似乎都可以正常工作。
同樣,如果程序是用單個線程執行的(即在多個線程之間不共享數組以進行更新),則這種特殊性永遠不會發生。
result_number,候選人,N都是全局變量。
void *primeNums(void *arg) {
pthread_mutex_lock(&mutex);
int *array = (int *) arg;
int is_prime = 0;
int j = 0;
while (result_number <= N) {
candidate++;
is_prime = checkPrime(candidate);
if (is_prime == 1) {
array[result_number] = candidate;
if (result_number == N) {
while (j < N) {
printf("%d\n", array[j]);
j++;
}
}
/* Test verification output; always accurate */
printf("Result number: %d = %d\n", result_number, candidate);
result_number++;
}
}
pthread_mutex_unlock(&mutex);
}
我確實不相信其他問題(如我所見)能解決這個問題(並且寧願找到答案來寫自己的問題)。 坦率地說,我可能沒有正確搜索。
編輯:示例不必要的輸出:-386877696 3 -395270400 32605 11 13 ...
從這里繼續進行。
我有一種直覺,如果不是傳遞數組並使用全局result_number,而是傳遞array + result_number並循環訪問局部變量: i = 0; while(i < N) {...}
i = 0; while(i < N) {...}
,您可以解決您的問題。 (假設array + result_number + N - 1
不會超出范圍)。
使用全局變量保存每個線程的范圍信息的問題是線程函數primeNums()
修改了其中的一些。 因此,如果您將result_number
設置為希望線程#1處理的范圍的開始來啟動您的第一個線程(線程#1),則線程#1在重置它的值以賦予線程#2時將不斷更改其值。 因此,線程2將不會處理您要處理的范圍。
我假設您希望每個線程在您的數組中處理單獨的索引范圍? 當前,您正在將指向數組開頭的指針傳遞給該函數,並使用全局變量將索引保存到該線程要處理的塊的數組中。
為了避免使用該全局索引,您要做的就是將指向偏移量的指針傳遞到要開始處理的數組中間。 因此,與其傳入指向開頭元素( array
)的值,不如傳入指向您要從其開始處理的元素的值( array + result_number
)。
如果這樣做,則在函數primeNums()
內部,它的作用就好像傳入的指針是數組的開始(即使它位於中間),並且您可以將循環從0
運行到N
因為您已經添加了調用該函數之前的result_number
。
說了這么多,我懷疑您仍然無法並行處理該數組(如果確實要這樣做),因為每個線程都依賴於candidate
被設置為前一個線程的最大值。 ..
為了保護“候選”不會被啟動其他線程的代碼同時更改(如果這樣做),您可以在互斥量(鎖定)上同步后獲取該變量的副本。 但是,老實說,我不確定該算法是否會讓您並行處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.