Test类在多线程环境中使用。 ThreadA通过调用hasToWait方法(ITestWaiter)询问是否必须等待ThreadB。 ThreadB完成工作后,他通过调用Test :: notify方法通知所有侍者。
您能告诉我在wait()方法中是否存在可能的死锁情况-在被互斥锁锁定的部分和对信号量获取方法的调用之间?
struct Semaphore {
bool acquire() { return WaitForSingleObject(sem, INFINITE); }
private:
Handle sem;
};
struct Test
{
bool wait(std::mutex mutex, const ITestWaiter *obj);
bool notify(std::mutex mutex);
private:
std::vector<Semaphore> waiters;
};
bool Test::wait(std::mutex mutex, const ITestWaiter *obj) {
Semaphore* sem;
{
std::unique_lock<std::mutex> mlock(mutex);
if (!obj->hasToWait())
return false;
sem = createSemaphoreAndPushBackToVector();
}
try {
sem->acquire();
}
catch (std::exception e) {}
return true;
}
bool Test::notify(std::mutex mutex) {
std::unique_lock<std::mutex> mlock(mutex);
//notify waiters by releasing the semaphore
return true;
}
答案 0 :(得分:0)
从您发布的代码来看,应该没有问题:在两种情况下,您都不会在持有锁期间阻塞。您只需执行一些小动作(一旦对向量进行迭代,就可以修改向量)。但是有些代码您没有显示!
首先,您要如何进行通知。我假设您使用CreateEvent
来获取句柄,并使用SetEvent
来进行通知-如果是这样,也没有问题。
然后是hasToWait
函数。可疑:您在已经锁定的情况下正在调用它!有什么理由吗? hasToWait
也有一些锁定吗?其他线程是否可能尝试锁定相同的功能?如果两个线程不能以相同的顺序获取锁,则存在死锁的风险。
如果没有单独的锁定,但是hasToWait
需要访问一些需要由相同互斥锁保护的资源,那么代码也可以。
如果没有锁定和不能访问共享资源,那么首先锁定互斥锁是徒劳的,只需要时间;在这种情况下,先检查会更有效:
if (obj->hasToWait())
{
Semaphore* sem;
{
std::unique_lock<std::mutex> mlock(mutex);
sem = createSemaphoreAndPushBackToVector();
}
try
{
sem->acquire();
}
catch (std::exception e)
{ }
}