2012-10-29 106 views
0

我一直有這個並行矩陣乘法代碼的麻煩,我試圖訪問我的結構中的數據成員時不斷收到錯誤。C++中的多線程矩陣乘法

這是我的主要功能:

struct arg_struct 
{ 
    int* arg1; 
    int* arg2; 
    int arg3; 
    int* arg4; 
}; 


int main() 
{ 
    pthread_t allthreads[4]; 
    int A [N*N]; 
    int B [N*N]; 
    int C [N*N]; 
    randomMatrix(A); 
    randomMatrix(B); 
    printMatrix(A); 
    printMatrix(B); 
    struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct)); 
    args.arg1 = A; 
    args.arg2 = B; 
    int x; 
    for (int i = 0; i < 4; i++) 
    { 
    args.arg3 = i; 
    args.arg4 = C; 
    x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args); 
    if(x!=0) 
    exit(1); 
    } 

    return 0; 
} 

和matrixMultiplication方法可以從另一C文件中使用:

void *matrixMultiplication(void* arguments) 
{ 
    struct arg_struct* args = (struct arg_struct*) arguments; 
    int block = args.arg3; 
    int* A = args.arg1; 
    int* B = args.arg2; 
    int* C = args->arg4; 
    free(args); 
    int startln = getStartLineFromBlock(block); 
    int startcol = getStartColumnFromBlock(block); 
    for (int i = startln; i < startln+(N/2); i++) 
    { 
     for (int j = startcol; j < startcol+(N/2); j++) 
     { 
      setMatrixValue(C,0,i,j); 
      for(int k = 0; k < N; k++) 
      { 
      C[i*N+j] += (getMatrixValue(A,i,k) * getMatrixValue(B,k,j)); 
      usleep(1); 
      } 
     } 
    } 
} 

另一個錯誤我正在創建線程時:「無效的轉換,從' void [](void)'[-fpermissive] 「

任何人都可以告訴我我做錯了什麼嗎?

+0

你得到的第一個錯誤是什麼? – BeeOnRope

+2

這是C除主函數 –

+0

另一個錯誤,_where_你明白了嗎?換句話說,你能指出你的錯誤在哪裏? –

回答

1

大老闆是正確的,他已經確定了問題,但增加了/增加了他所做的回覆。

選項1: 只需創建的循環的arg_struct並設置成員,然後將其穿過:

for(...) 
{ 
    struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct)); 
    args->arg1 = A; 
    args->arg2 = B; //set up args as now... 
    ... 
    x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args); 
    .... 
} 

保持在線程free電話,但現在你可以再使用通過直接結構化而不是在你的線程中創建局部變量。

選項2: 它看起來像你想從結構體內部複製參數到線程,所以你不需要動態分配。

只需創建一個arg_struct並設置成員,然後將其穿過:

arg_struct args; 
//set up args as now... 
for(...) 
{ 
    ... 
    x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)&args); 
} 

然後取出free電話。

但是,正如James指出的那樣,您需要在結構上的線程/父級進行同步,以確保它沒有被更改。這意味着互斥體或其他機制。因此,分配到for循環的移動可能更容易開始。

第2部分:

我的工作窗口(所以我不能嘗試目前),但在pthread_create參數3指的是被定義爲void* matrixMultiplication(void*);線程函數matrixMultiplication - 它看起來是正確的我(簽名明智)從網上手冊頁void* fn (void*)

我想我會不得不推遲到別人你的第二個錯誤。這個帖子是一個comunnity維基條目,所以如果需要的話可以把這個答案放進去。

+0

非常感謝John,它解決了我的數據成員訪問問題,但是我仍然收到在我的OP中提到的第二個錯誤消息: 「parallel.c:41:82:error:void invalid(*)(int * ,int *,int,int *)'到'void *(*)(void *)'[-fpermissive] /usr/include/pthread。h:225:12:error:初始化參數3'int pthread_create(pthread_t *,const pthread_attr_t *,void *(*)(void *),void *)'[-fpermissive] 「 – Splintz

+0

如果您打算對所有線程使用相同的'args',你必須添加同步代碼以確保剛剛啓動的線程在你修改之前完成,以便開始下一個線程(如果你使用'boost: :線程和按值傳遞,這是爲你完成的。) –

+0

@詹姆斯好點 - 我會更新這個以反映 – Caribou

4

首先混合使用C和C++,使用普通C或使用C++,在C++中,您可以簡單地使用newdelete

但是,你錯誤的原因是你在一個地方分配arg_struct並在4個線程中釋放它。你應該爲每個線程分配一個arg_struct

+0

在單獨的線程完成之前,他也從'main'返回。他的塊包含指向局部變量的指針,一旦他從函數返回,這些指針就會停頓。 –

1

我不清楚你在做什麼。你開始一些線程, 然後你從main返回(退出該過程),然後得到它們的任何 結果。

在這種情況下,我很可能不是直接使用任何動態分配。 (我會使用std::vector作爲矩陣,這將在內部使用動態 分配。)沒有理由動態分配 arg_struct,因爲它可以安全地複製。當然,你必須等待,直到每個線程成功地提取其數據,然後循環構建下一個線程。這通常會使用 一個條件來完成:新線程將解除對條件的阻止,一旦它從arg_struct(或者甚至更好,您可以使用boost::thread,它爲您完成這部分)提取參數 。或者,您可以使用的arg_struct數組,但絕對沒有理由 動態分配它們。 (如果由於某種原因,你不能使用 std::vectorABC,你要動態分配這些 ,以避免堆棧溢出的風險。但是 std::vector是一個更好的解決方案。)

最後,當然,在離開main之前,您必須等待所有線程完成 。否則,這些線程將繼續處理 不再存在的數據。在這種情況下,您應該在退出main之前的所有線程都爲 pthread_join。大概 也是,你想用乘法結果 做些什麼,但在任何情況下,在所有線程完成 訪問矩陣之前退出main都會導致未定義的行爲。