我有以下类方法:
myclass::concurFnc(bool changingVar )
{
int i;
mIdMutex.lock();
i = mId++;
mIdMutex.unlock;
std::cout << "Try Waiting: " << i << std::endl;
std::mutex waitValidMutex;
std::unique_lock<std::mutex> l(waitValidMutex);
mNoOtherThreadDiffCompareVal.wait(l, [this, &changingVar]()
{
mSemMutex.lock();
bool result = false;
if(myclass::staticVar == changingVar)
{
std::cout << "Same var : " << changingVar << i << std::endl;
result = true;
--mSem;
} else if(mSem == 1)
{
std::cout << "Only one in crit section: " << i << std::endl;
--mSem;
myclass::staticVar = changingVar;
result = true;
} else
{
std::cout << "wait: " << i << std::endl;
result = false;
}
std::cout << "Sem is now " << mSem << std::endl;
mSemMutex.unlock();
return result;
});
//DO STUFF
mSemMutex.lock();
++mSem;
std::cout << "In the end sem is: " << mSem << std::endl;
mSemMutex.unlock();
mNoOtherThreadDiffCompareVal.notify_all();
}
//class Member Variables
std::mutex mSemMutex;
std::mutex mIdMutex;
std::condition_variable mNoOtherThreadDiffCompareVal;
int32_t mSem;
int32_t mId;
myclass::myclass() : mSem(1), mId(0)
{
}
void myclass::startThreads()
{
const int AMOUNT_OF_PROCESSES = 3
std::vector<std::shared_ptr<boost::thread> > processes;
for (size_t t_id = 0; t_id < AMOUNT_OF_PROCESSES; ++t_id)
{
bool changingVar = getVarSomewhere();
std::shared_ptr<boost::thread> thread_ptr(new boost::thread(&myclass::concurFnc, this, changingVar));
processes.push_back(thread_ptr);
}
for (size_t t_id = 0; t_id < AMOUNT_OF_PROCESSES; ++t_id) {
processes[t_id]->join();
}
}
如果changingVar与当前位于// DO STUFF内的所有其他调用者相同(或者如果是唯一的调用者),则应该允许输入// DO STUFF部分 该函数从boost :: threads中的函数调用。
有时会发生执行停止,因为它仍然在等待,尽管mSem为1并且应该调用notify_all()
执行停止前的输出是:
wait: 3248
Sem is now 0
Try Waiting: 3249
wait: 3249
Sem is now 0
In the end sem is: 1
Only one in crit section: 3249
Sem is now 0
Try Waiting: 3250
wait: 3250
Sem is now 0
In the end sem is: 1
Only one in crit section: 3250
Sem is now 0
In the end sem is: 1
Try Waiting: 3251
Same comp val : 0 of: 3251
Sem is now 0
.In the end sem is: 1
到目前为止,我无法真正重现它。
该计划再次开始运作。 Mabey是因为我把gdb附加到它上面,或者某种程度上有很大的延迟。
答案 0 :(得分:1)
条件变量的使用模式非常奇怪。
传入条件变量的wait
函数的互斥锁应始终是保护您正在等待的条件的互斥锁,这里似乎是mSemMutex
。
这是有道理的,因为要检查是否满足等待条件,您仍需要锁定此互斥锁。考虑到这一点,你可以完全摆脱waitValidMutex
并用mSemMutex
替换它的所有用途。
另请注意,目前,由于waitValidMutex
是本地互斥锁,因此实际上risk undefined behavior when calling wait
:
如果lock.mutex()与该互斥锁不是同一个互斥锁,则调用此函数 由当前正在等待的所有其他线程使用 条件变量是未定义的行为。