从概念上讲,如何使用tbb::parallel_for
阻止tbb:spin_mutex
来电中的关键部分?关键部分少于20条指令,因此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);
}
...
...
}
);
...
...
}
功能A:
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_mutex
中设置functionA()
,以便在整个线程中共享mutex
,并且线程不会超越对方尝试执行关键部分同时进行。
注意:假设function()
和functionA()
属于两个单独的C ++类,并且在function()
和functionA()
为成员的两个类之间没有基于类的继承功能
答案 0 :(得分: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及更高版本(因为你需要&#34; magic static&#34;,即静态变量初始化的线程安全性)。
答案 1 :(得分: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
}
...
...
}
);
...
...
}
和functionA:
// 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
}
}
...
...
}