gpt4 book ai didi

c++ - 等待 WaitForMultipleObjects

转载 作者:可可西里 更新时间:2023-11-01 10:01:55 38 4
gpt4 key购买 nike

我正在尝试为我的 FileWatcher 类编写单元测试。

FileWatcher 派生自 Thread 类并使用 WaitForMultipleObjects 在其线程过程中等待两个句柄:

  1. FindFirstChangeNotification返回的句柄
  2. 让我取消上述等待的事件句柄。

所以基本上 FileWatcher 正在等待最先发生的事情:文件更改或者我告诉它停止监视。

现在,在尝试编写测试此类的代码时,我需要等待它开始等待。

伪代码:

FileWatcher.Wait(INFINITE)
ChangeFile()
// Verify that FileWatcher works (with some other event - unimportant...)

问题是存在竞争条件。我需要首先确保 FileWatcher 已开始等待(即它的线程现在在 WaitForMultipleObjects 上被阻塞),然后才能在第 2 行触发文件更改。我不想使用 Sleeps,因为它看起来很老套,而且在调试时肯定会给我带来问题。

我熟悉SignalObjectAndWait,但它并没有真正解决我的问题,因为我需要它来“SignalObjectAndWaitOnMultipleObjects”...

有什么想法吗?


编辑

为了澄清一点,这里是 FileWatcher 类的简化版本:

// Inherit from this class, override OnChange, and call Start() to turn on monitoring. 
class FileChangeWatcher : public Utils::Thread
{
public:
// File must exist before constructing this instance
FileChangeWatcher(const std::string& filename);
virtual int Run();
virtual void OnChange() = 0;
};

它继承自Thread,并实现了线程函数,看起来是这样的(非常简化):

_changeEvent = ::FindFirstChangeNotificationW(wfn.c_str(), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);

HANDLE events[2] = { _changeEvent, m_hStopEvent };

DWORD hWaitDone = WAIT_OBJECT_0;
while (hWaitDone == WAIT_OBJECT_0)
{
hWaitDone = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);

if (hWaitDone == WAIT_OBJECT_0)
OnChange();
else
return Thread::THREAD_ABORTED;
}
return THREAD_FINISHED;

请注意,线程函数等待两个句柄,一个是更改通知,另一个是“停止线程”事件(继承自 Thread)。

现在测试这个类的代码如下所示:

class TestFileWatcher : public FileChangeWatcher
{
public:
bool Changed;
Event evtDone;
TestFileWatcher(const std::string& fname) : FileChangeWatcher(fname) { Changed = false; }
virtual void OnChange()
{
Changed = true;
evtDone.Set();
}
};

并从 CPPUnit 测试中调用:

std::string tempFile = TempFilePath();
StringToFile("Hello, file", tempFile);
TestFileWatcher tfw(tempFile);
tfw.Start();
::Sleep(100); // Ugly, but we have to wait for monitor to kick in in worker thread
StringToFile("Modify me", tempFile);
tfw.evtDone.Wait(INFINITE);
CPPUNIT_ASSERT(tfw.Changed);

我们的想法是摆脱中间的 sleep 。

最佳答案

没有竞争,您不必等待 FileWatcher 进入 WaitForMultipleObjects。如果您在调用函数之前执行更改,它将立即返回。

编辑:我现在可以看到比赛了。你为什么不移动以下行

_changeEvent = ::FindFirstChangeNotificationW(/*...*/);

从线程函数到FileChangeWatcher的构造函数?这样,您就可以确定在 StringToFile 函数被调用时,该文件已被监视。

关于c++ - 等待 WaitForMultipleObjects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2037863/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com