2017-08-24 61 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及更高版本(因为您需要“魔术静态”,即静态变量初始化的线程安全性)。

相关问题