2017-08-24 156 views
0

概念,我怎麼能阻止使用​​一個tbb::parallel_for裏面調用一個關鍵部分?關鍵部分少於20條指令,所以spin_mutex是理想選擇。例如下面的虛擬代碼說明了情況:內parallel_for時TBB spin_mutex阻止一個關鍵部分

function() { 
    // I'm using lambda functions in parallel_for call here. The parallel_for 
    // is multithreading across the size of the vector customVec 
    tbb::parallel_for(
     tbb::blocked_range<vector<CustomeType>::iterator>(customVec.begin(), customVec.end(), 1), 
     [&](tbb::blocked_range<vector<CustomType>::iterator> customVec) { 
      for (vector<CustomType>::iterator it = customVec.begin(); it != customVec.end(); it++) { 
       CustomType item = *it; 
       ... 
       ... 

       // This is the cross-functional call that each thread will call 
       // critical section is in-side the functionA 
       item->functionA(param1, param2); 
      } 

      ... 
      ... 
     } 
    ); 

    ... 
    ... 
} 

與泛函:

functionA (Type1 param1, Type2 param2) { 
    if (conditionX) { 
     /* This file read is the critical section. So basically, need to 
     block multiple threads reading the same file to reduce I/O cost 
     and redundancy. Since file read can be stored in a global variable 
     that can be accessed in memory by other threads */ 

     fileRead(filename); // Critical line that need to be protected 
    } 
    ... 
    ... 
} 

我正在掙扎是如何我可以設置spin_mutexfunctionA()使得mutex跨線程共享線程不會超越對方,試圖同時執行關鍵部分。

注意:假設function()functionA()屬於兩個單獨的C++類和存在具有function()functionA()作爲成員函數

回答

0

我只找到了解決這兩個類之間沒有基於類的繼承。可能不是最佳的,但解決了我的問題。因此,將它作爲可能遇到相同問題的人的答案發布。

基本上,解決方法是定義spin_mutex對象在parallel_for之外,並將它作爲參考傳遞給函數調用。我已經發布了同樣的代碼示例從問題與下面的解決方案:

tbb::spin_mutex mtx; // Declare spin_mutex object 
function() { 
    // I'm using lambda functions in parallel_for call here. The parallel_for 
    // is multithreading across the size of the vector customVec 
    tbb::parallel_for(
     tbb::blocked_range<vector<CustomeType>::iterator>(customVec.begin(), customVec.end(), 1), 
     [&](tbb::blocked_range<vector<CustomType>::iterator> customVec) { 
      for (vector<CustomType>::iterator it = customVec.begin(); it != customVec.end(); it++) { 
       CustomType item = *it; 
       ... 
       ... 

       // This is the cross-functional call that each thread will call 
       // critical section is in-side the functionA 
       item->functionA(param1, param2, mtx); // pass object as a reference 
      } 

      ... 
      ... 
     } 
    ); 

    ... 
    ... 
} 

和泛函:

// Pass the spin_mutex object by reference 
functionA (Type1 param1, Type2 param2, tbb::spin_mutex& mtx) { 
    if (conditionX) { 
     /* This file read is the critical section. So basically, need to 
     block multiple threads reading the same file to reduce I/O cost 
     and redundancy. Since file read can be stored in a global variable 
     that can be accessed in memory by other threads */ 

     // Acquire a scope lock 
     { 
      tbb::spin_mutex::scoped_lock lock(mtx); 
      fileRead(filename); // Critical line that need to be protected 
     } 
    } 
    ... 
    ... 
} 
1

你可能要考慮使用靜態spin_mutex裏面的功能:

functionA (Type1 param1, Type2 param2) { 
    if (conditionX) { 
     /* This file read is the critical section. So basically, need to 
     block multiple threads reading the same file to reduce I/O cost 
     and redundancy. Since file read can be stored in a global variable 
     that can be accessed in memory by other threads */ 

     // A static mutex that is shared across all invocations of the function. 
     static tbb::spin_mutex mtx; 
     // Acquire a lock 
     tbb::spin_mutex::scoped_lock lock(mtx); 
     fileRead(filename); // Critical line that need to be protected 
    } 
    ... 
    ... 
} 

請注意,它僅適用於C++ 11及更高版本(因爲您需要「魔術靜態」,即靜態變量初始化的線程安全性)。