我有一個使用MPI Pthread的程式。 我在實作pthreads來共享一個陣列的讀/寫方面遇到了困難。 我在這里做了一個模擬代碼,它模擬了這個問題。
#include <iostream>
#include <unistd.h>
#include <pthread.h>
結構 args {
double* array;
int start;
int stop;
double myVal;
double* row;
pthread_barrier_t* barrier。
};
void* mythread(void* arguments){
struct args* args_ = (struct args*)arguments。
double* array = args_-> array;
int start = args_->start;
int stop = args_->stop;
double myVal = args_->myVal;
pthread_barrier_t* barrier = args_-> barrier;
double* row = args_->row。
for(int i = start; i < stop; i ){
pthread_barrier_wait(barrier)。
for(int j =0; j < 10; j ){
double a = row[j];
int ind = i*10 j。
array[ind] = a myVal;
}
}
}
int main(){
pthread_t threads[50] 。
int start_ = 0;
double* array_0 = NULL;
array_0 = new double[100*10] 。
double* row = NULL;
row = new double[10] 。
pthread_barrier_t barrier。
(void)pthread_barrier_init(&barrier, NULL, 50 1) 。
for(int n = 0; n < 50; n ){
struct args args_;
args_.start = start_;
args_.stop = start_ 2;
start_ = start_ 2;
args_.array = &array_0[0]。
args_.myVal = n;
args_.row = row;
args_.barrier = &barrier;
(void)pthread_create(&threads[n], NULL, mythread, (void*)&args_) 。
}
for(int i = 0; i < 2; i ){
for(int k = 0; k < 10; k ){
row[k] = i 1;
}
//usleep(100);
pthread_barrier_wait(&barrier)。
}
for(int n = 0; n < 50; n ){
(void)pthread_join(threads[n], NULL)。
}
// print; }
for(int i = 0; i < 100; i ){
for(int j = 0; j < 10; j ){
int ind = i*10 j;
std::cout << " "/span> << array_0[ind];
}
std::cout << std::endl;
}
return 0;
主系統產生了50個執行緒。 Barrier被初始化為50 1(包括主執行緒)。 這應該在pthread_barrier_wait()呼叫中同步所有的51個執行緒,但是阻塞的等待呼叫似乎不允許 "行 "陣列的寫入回圈在釋放前完成。
預期結果應該是:
1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5
.
.
.
.
.
.
等等。
實際輸出是半隨機的。 在一些執行緒中,它完成了序列,而在其他執行緒中,它顯示為零,就像 "行 "從未被填入一樣。 在寫入 "row "陣列后添加usleep()也無濟于事--并不是說我的代碼中可以有睡眠函式。 這使我相信我不明白指標陣列是如何在執行緒之間正確共享的。 我是C 的新手,所以希望得到任何幫助。
uj5u.com熱心網友回復:
在你的回圈中,你創建了一個struct args物件,然后你把這個物件的地址傳遞給pthread_create。然后這個物件在回圈迭代結束時被立即 "銷毀",并在下一次迭代時創建一個新的物件,然而,新創建的執行緒仍然有對這個舊的 "銷毀 "物件的參考。
你需要確保你傳遞給pthread_create的物件能持續足夠長的時間,以便:
- 執行緒對它進行自己的復制 。
- 執行緒完成 。
作為一個非常簡單的方法,你可以把_args的宣告移到回圈之外,并把它變成一個陣列,像這樣:
struct args args_[50] 。
for(int n = 0; n < 50; n ){
args_[n].start = start_;
args_[n].stop = start_ 2;
start_ = start_ 2;
args_[n].array = &array_0[0] 。
args_[n].myVal = n;
args_[n].row = row;
args_[n].barrier = &barrier;
(void)pthread_create(&threads[n], NULL, mythread, (void*)&args_[n]) 。
}
args_[]的壽命現在比每個執行緒都長。另外,你可以動態地分配你的結構args(例如,用new)并在執行緒中消耗該物件(例如,用delete)。或者如果你使用C 11或更高版本,你可以使用std::shared_ptr和std::thread,有一些關于這兩者如何相互作用的檔案這里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/308343.html
標籤:
上一篇:將文本框改為資料網格視圖
