等待方法中可能出现死锁情况?

时间:2019-02-26 10:01:54

标签: c++

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;
}

1 个答案:

答案 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)
    { }
}