如何确定 Win32 事件的信号状态
How to determine Signalled state of Win32 Event?
我创建了一个自动重置事件对象,如下所示:
handle = CreateEvent(NULL, true, false, NULL);
。并且(出于某些单元测试目的)我想检查它是否在某个点发出信号。我知道使用事件的"正确"方式 - 这纯粹是为了诊断工具。
对于手动重置事件,我可以使用...
bool signalled = WaitForSingleObjectEx(handle, 0, true) != WAIT_TIMEOUT;
。但对于具有重置它们的副作用的自动重置事件。我想我可以试试这个,但我有一种感觉,应该有一种不那么危险的方式......?
bool isSignalled(HANDLE handle)
{
bool signalled = WaitForSingleObjectEx(handle, 0, true) != WAIT_TIMEOUT;
// warning - event is now reset. Maybe need to wrap this in a critical section or similar?
if (signalled)
SetEvent(handle);
return signalled;
}
更新:
咖啡开始了,我错了!
使用超时为零的 WaitForSingleObject 来确定事件是否已发出信号,如果事件发出信号(及其自动重置事件),则会导致信号被清除。您可以通过连续两次调用 WaitForSingleObject 来验证这一点。
必须先释放等待线程,然后才能重置为自动重置初始化的事件。
http://msdn.microsoft.com/en-us/library/ms682396(VS.85).aspx
当您在超时为零的情况下调用 WaitForSingleObjectEx 时,您的线程不会成为等待器。
http://msdn.microsoft.com/en-us/library/ms687036(VS.85).aspx
如果 dw毫秒为零,则 函数不进入等待状态 如果不符合标准;它总是 立即返回。
我没有看到一个简单的方法。 您可以出于测试目的"模拟"事件。
将事件包装在 C++ 对象中,并更改所有代码以使用其方法。
class MockEvent {
public:
MockEvent () : m_handle(::CreateEvent(NULL, TRUE, FALSE, NULL) {}
~MockEvent () { ::CloseHandle(m_handle); }
BOOL Set() { return ::SetEvent(m_handle); }
DWORD Wait(DWORD timeout = INFINITE) {
return ::WaitForSingleObject(m_handle, timeout);
}
private:
HANDLE m_handle;
// Do not implement copy or assignment:
MockEvent(const MockEvent &);
MockEvent &operator=(const MockEvent &);
};
然后,您需要使用某种引用计数指针,该指针可以按照原始 HANDLE 的方式传递和复制:
typedef std::tr1::shared_ptr<MockEvent> MockEventPtr;
将使用原始句柄的所有代码替换为 MockEventPtr。
// Original code:
HANDLE hEvent = CreateEvent(NULL, true, false, NULL);
// Becomes:
MockEventPtr pEvent(new MockEvent);
// Original code:
SetEvent(hEvent);
// Becomes:
pEvent->Set();
等等。
现在,对于诊断工具,可以扩展 MockEvent 以跟踪状态并公开显示当前状态的方法。
class MockEvent {
public:
MockEvent () :
m_handle(::CreateEvent(NULL, TRUE, FALSE, NULL),
m_signaled(false) {
::InitializeCriticalSection(&m_cs);
}
~MockEvent () {
::DeleteCriticalSection(&m_cs);
::CloseHandle(m_handle);
}
BOOL Set() {
::EnterCriticalSection(&m_cs);
m_signaled = true;
BOOL result = ::SetEvent(m_handle);
::LeaveCriticalSection(&m_cs);
return result;
}
DWORD Wait(DWORD timeout = INFINITE) {
::EnterCriticalSection(&m_cs);
DWORD result = ::WaitForSingleObject(m_handle, timeout);
if (result == WAIT_OBJECT_0) {
m_signaled = false;
}
::LeaveCriticalSection(&m_cs);
return result;
}
// The result of this may be obsolete by the time you get it.
bool IsSignaled() const { return m_signaled; }
private:
HANDLE m_handle;
bool m_signaled;
CRITICAL_SECTION m_cs;
// Do not implement copy or assignment:
MockEvent(const MockEvent &);
MockEvent &operator=(const MockEvent &);
};
这是未经测试的代码。 在实际代码中,我也会包装CRITICAL_SECTION。 请注意,如果另一个线程更改状态,IsSignaled 的结果可能会在您获得它的那一刻过时。 我假设这是为了测试代码,这些代码将在状态应该以某种方式进行检查时进行检查。
- Qt VTK交互风格的信号到小部件
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何在没有信号的情况下从C++执行QML插槽
- 线程之间的布尔停止信号
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- OSX MetalKit CVMetalTextureCacheCreateTextureFromImage失败,状态:
- 当用户在qtablewidget中输入单元格时,如何获得信号?C++
- 有可能在信号处理程序中设置promise吗
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- std::future_error:无关联状态
- 信号处理程序和本地状态
- 如何设置并发::事件对象,仅当它现在未处于信号状态时
- 当使用信号处理程序触发事件时,如何使boost.msm正确更改状态
- Qt QState机器同步问题:初始状态未在启动信号上设置
- 如何在Qt中检查信号状态
- 如何确定 Win32 事件的信号状态
- 在Linux/ c++中,发送给线程/进程的信号是否使其变为活动状态?