2011-02-12 93 views
2

假設您有一個函數來計算大數組中值的出現次數。您希望通過讓每個線程統計它自己的數組部分中的出現次數,然後將結果添加到一起來多線程化該函數。我們可以假設每個線程都有一個唯一的等級(從0到N-1),並且每個線程都會在大約同一時間調用該函數。例如爲:多線程函數可以使用靜態數組在線程之間共享數據嗎?

int count[N]; // global array 

int countOccurences() 
{ 
    count[rank] = /* count occurences in one part of the array */ 
    // wait until all other threads reached this point 
    int total = 0; 
    for (int i=0; i<N; i++) 
     total += count[i]; 
    return total; 
} 

問題是,在上面的例子中,可以予移動count數組的countOccurences()主體作爲一個靜態變量?我不需要它存在於函數體外的任何地方:線程之間會共享靜態數組嗎?

回答

2

的回答你的問題是肯定的,線程可以訪問全局數據和靜態數據在同一個編譯單元中,但是關於「在線程之間共享數據」這個話題還有更多的內容需要理解。

對於每個線程,有一個相應的功能(「線程功能」),一個線程將在與其他線程並行地執行。一個線程可以通過指針或引用參數,全局數據,與線程函數相同的編譯單元中的靜態數據,或者通過其他函數可讀/可修改的全局和/或靜態數據訪問該函數可以訪問的任何內容線程函數可以調用。您應該能夠確定給定函數可以讀取或修改的每個內存區域。給定線程函數的那些內存區域恰好是線程有權訪問的內存區域。

很容易看出,全局數據和靜態數據在同一編譯單元是一個線程函數訪問的,所以這就是爲什麼在回答你的問題是「是」。你可能想看看

一件事是OpenMP的,它有一個並行操作countOccurrences內置的結構(所謂的「減排」):

#include <stddef.h> 
#include <stdio.h> 
#include <stdlib.h> 

size_t countOccurrences(const int *arr, size_t n, int which) { 
    size_t count, i; 

    count = 0; 

    #pragma omp parallel for reduction(+:count) 
    for (i = 0; i < n; ++i) { 
     if (arr[i] == which) 
      ++count; 
    } 

    return count; 
} 

int main() 
{ 
    int arr[] = { 3, 5, -1, -1, 0 }; 

    size_t count = countOccurrences(arr, sizeof (arr)/sizeof (arr[0]), -1); 
    printf("count = %d\n", (int) count); 
    return EXIT_SUCCESS; 
} 
2

是的,你可以,因爲你的線程完成它們的工作你從countOccurences回來之前。只是通過參考第i個元素到第i個線程功能,因此它可以訪問它

是這樣的:

#include <boost/thread.hpp> 
#include <numeric> 
#include <boost/bind.hpp> 

void thread_function(int& result) 
{ 
    // your implementation 
} 

size_t const n = 100; 

int countOccurences() 
{ 
    int count[n]; 
    boost::thread_group group; 
    for (int i = 0; i != n; ++i) 
     group.create_thread(boost::bind(thread_function, boost::ref(count[i]))); 
    group.join_all(); 
    return std::accumulate(count, count + n, 0); 
} 
+0

對不起,我不完全在問題中明確。 `countOccurences()`已經在線程函數中。 – suszterpatt 2011-02-12 18:37:58