我发现一些声称能够使线程在准确的时间内睡眠的代码。测试代码,它似乎很好,但它在短时间后总是死锁。EnterCriticalSection死锁
这是原始代码。我在进入和离开关键部分之前放置了相片,并且看到它有时会连续两次离开或进入。它在Wait函数内的EnterCriticalSection调用中似乎陷入死锁。
有没有一种方法可以修改此代码以保留其功能而不会造成死锁?
//----------------------------------------------------------------
class PreciseTimer
{
public:
PreciseTimer() : mRes(0), toLeave(false), stopCounter(-1)
{
InitializeCriticalSection(&crit);
mRes = timeSetEvent(1, 0, &TimerProc, (DWORD)this,
TIME_PERIODIC);
}
virtual ~PreciseTimer()
{
mRes = timeKillEvent(mRes);
DeleteCriticalSection(&crit);
}
///////////////////////////////////////////////////////////////
// Function name : Wait
// Description : Waits for the required duration of msecs.
// : Timer resolution is precisely 1 msec
// Return type : void :
// Argument : int timeout : timeout in msecs
///////////////////////////////////////////////////////////////
void Wait(int timeout)
{
if (timeout)
{
stopCounter = timeout;
toLeave = true;
// this will do the actual delay - timer callback shares
// same crit section
EnterCriticalSection(&crit);
LeaveCriticalSection(&crit);
}
}
///////////////////////////////////////////////////////////////
// Function name : TimerProc
// Description : Timer callback procedure that is called
// : every 1msec
// : by high resolution media timers
// Return type : void CALLBACK :
// Argument : UINT uiID :
// Argument : UINT uiMsg :
// Argument : DWORD dwUser :
// Argument : DWORD dw1 :
// Argument : DWORD dw2 :
///////////////////////////////////////////////////////////////
static void CALLBACK TimerProc(UINT uiID, UINT uiMsg, DWORD
dwUser, DWORD dw1, DWORD dw2)
{
static volatile bool entered = false;
PreciseTimer* pThis = (PreciseTimer*)dwUser;
if (pThis)
{
if (!entered && !pThis->toLeave) // block section as
// soon as we can
{
entered = true;
EnterCriticalSection(&pThis->crit);
}
else if (pThis->toLeave && pThis->stopCounter == 0)
// leave section
// when counter
// has expired
{
pThis->toLeave = false;
entered = false;
LeaveCriticalSection(&pThis->crit);
}
else if (pThis->stopCounter > 0) // if counter is set
// to anything, then
// continue to drop
// it...
--pThis->stopCounter;
}
}
private:
MMRESULT mRes;
CRITICAL_SECTION crit;
volatile bool toLeave;
volatile int stopCounter;
};
你如何使用它来导致死锁? – Chad
对不起,这个类中唯一的函数是Wait,并且在短暂的随机时间内调用它会导致死锁 – user3124047
但是要调用Wait(),您必须有一个对象。你如何创建该对象?显示你的'main'功能。 – Chad