編輯:謝謝大家,我使用管道調整了我的代碼并與主行程通信。
我的代碼現在回傳“12”,它是陣列一半的總和。
另一半不在回報中求和。
這是新代碼:(我知道記憶體泄漏和奇數陣列,我只是想掌握邏輯)
#define THRESHOLD 2
int fd[2];
int compute(int *arr, int len) {
if (len > THRESHOLD) {
if (fork() == 0) {
close(fd[0]);
int half = (len / 2);
int *left = malloc(half * sizeof(int));
int *right = malloc(half * sizeof(int));
memcpy(left, arr, half * sizeof(int));
memcpy(right, arr half, half * sizeof(int));
int res = compute(left, half) compute(right, half);
write(fd[1], &res, sizeof(int));
exit(0);
close(fd[1]);
} else {
close(fd[1]);
wait(NULL);
int res;
read(fd[0], &res, sizeof(int));
return res;
}
}
else {
return arr[0] arr[1];
exit(0);
}
}
int main(int argc, char *argv[]) {
pipe(fd);
int arr[] = {1, 2, 4, 5, 2, 1, 5, 1};
int res = compute(arr, 8);
printf("%d\n", res);
exit(EXIT_SUCCESS);
}
我正在嘗試使用多個行程對一組整數求和。
這是我的代碼:
#define THRESHOLD 2
int compute(int *arr, int len) {
if (len > THRESHOLD) {
if (fork() == 0) {
int half = (len / 2);
int *left = malloc(half * sizeof(int));
int *right = malloc(half * sizeof(int));
memcpy(left, arr, half * sizeof(int));
memcpy(right, arr half, half * sizeof(int));
return compute(left, half) compute(right, half);
} else {
wait(NULL);
}
}
else {
return arr[0] arr[1];
exit(0);
}
}
int main(int argc, char *argv[]) {
int arr[] = {1, 2, 4, 5, 2, 1, 5, 1};
int res = compute(arr, 8);
printf("%d\n", res);
exit(EXIT_SUCCESS);
}
這會回傳有害的結果,有時:
3
6231
6231
12460
6228
有時 :
3
6214
6214
12426
6211
等等...
有什么問題嗎?
uj5u.com熱心網友回復:
顯示的代碼中有多個錯誤。
if (fork() == 0) {
fork() 創建一個新行程,而不是一個新執行緒。子行程中發生的任何事情都不會對父行程產生任何影響。
父行程執行以下操作:
wait(NULL);
這將等待子行程完成。好的,子行程將完成。但無論它做什么,父行程完全不知道它。這是一個完全不同的程序。無論它做了什么,對于父行程來說都將是一個完全的謎。
這也是這個函式中的最后一個陳述句,它沒有return任何值。這是未定義的行為,是垃圾輸出的主要原因。
子行程的邏輯也存在重大問題:
int *left = malloc(half * sizeof(int));
int *right = malloc(half * sizeof(int));
memcpy(left, arr, half * sizeof(int));
memcpy(right, arr half, half * sizeof(int));
return compute(left, half) compute(right, half);
如果len是奇數,這將錯過陣列中的值之一。即使這里的所有其他問題都得到解決,結果總和也是錯誤的。奇數大小的陣列將從總和中省略其值之一。
這也會泄漏記憶體。該malloc版記憶體空間還沒有任何地方釋放。此外,無論如何,這些都沒有完成任何有用的事情。同樣的事情可以簡單地通過做適當的指標運算來完成arr,并通過調整值arr,并len以遞回呼叫,無需浪費時間和記憶體,對malloc荷蘭國際集團和memcpy荷蘭國際集團的這大塊。這里實際上不需要malloc.
但是解決這個問題并不能解決這個基本事實,即原始父行程fork是子行程,等待它完成,然后離開compute()而不回傳任何東西。無論如何,它真的沒有任何東西可以回傳,因為一切都發生在一個完全不同的子行程中。
如果您打算使用行程,則有必要為每個子行程實作某種機制,以某種形式或方式將其計算出的總和傳輸到父行程——可能是管道,也可能是臨時檔案,或者也許是其他方式。行程退出代碼的范圍非常有限,完全無法用于此目的。
如果你的目的是要真正使用的執行緒,而不是程序,所有的使用fork()和wait()需要被替換std::thread,而額外的邏輯將不得不以擁有所有的執行執行緒傳達他們的結果,他們計算的部分和,父要寫入執行執行緒。
無論是執行緒還是行程,顯示的代碼都缺少所需功能的主要部分,需要實作。在顯示的代碼正常作業之前,需要修復上述所有問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/403030.html
標籤:
上一篇:JavaExecutorServiceinvokeAll多任務決議
下一篇:創建執行緒花費的時間太長
