gpt4 book ai didi

c++ - 简单的线程计时器,请进行健全性检查

转载 作者:行者123 更新时间:2023-11-28 02:31:23 25 4
gpt4 key购买 nike

我制作了一个非常简单的线程计时器类,考虑到 MT 代码的缺陷,我想请您进行完整性检查。这里的想法是启动一个线程,然后不断地循环等待一个变量。如果等待超时,则超出间隔,我们调用回调。如果变量被通知,线程应该退出,我们不调用回调。

我不确定的一件事是我的代码在析构函数中发生了什么,假设线程可能在那里是可连接的(只是)。我可以在析构函数中加入线程以确保它已完成吗?

这是类:

class TimerThreaded
{
public:

TimerThreaded() {}
~TimerThreaded()
{
if (MyThread.joinable())
Stop();
}

void Start(std::chrono::milliseconds const & interval, std::function<void(void)> const & callback)
{
if (MyThread.joinable())
Stop();

MyThread = std::thread([=]()
{
for (;;)
{
auto locked = std::unique_lock<std::mutex>(MyMutex);
auto result = MyTerminate.wait_for(locked, interval);

if (result == std::cv_status::timeout)
callback();
else
return;
}
});
}

void Stop()
{
MyTerminate.notify_all();
}

private:

std::thread MyThread;
std::mutex MyMutex;
std::condition_variable MyTerminate;
};

我想一个更好的问题可能是让某人向我指出一个非常简单的线程计时器,如果某个地方已经可用的话。

最佳答案

Can I join a thread in a destructor to make sure it's finished?

不仅您可以,而且这样做是很常见的。如果线程实例在销毁时是可连接的(即仍在运行),将调用 terminate

For some reason result is always timeout. It never seems to get signalled and so never stops. Is it correct? notify_all should unblock the wait_for?

只有线程恰好当时在cv上才能解除阻塞。您可能正在做的是调用 Start ,然后在线程开始运行并开始等待之前立即调用 Stop (或者可能在 callback 运行时).在这种情况下,线程永远不会收到通知。

您的代码还有另一个问题。即使您没有显式调用 notify_X,阻塞的线程也可能在某些实现中被虚假地唤醒。这会导致您的计时器无缘无故地随机停止。

我建议您添加一个标志变量,指示是否已调用 Stop。这将解决上述两个问题。这是使用条件变量的典型方式。我什至为您编写了代码:

class TimerThreaded
{
...
MyThread = std::thread([=]()
{
for (;;)
{
auto locked = std::unique_lock<std::mutex>(MyMutex);
auto result = MyTerminate.wait_for(locked, interval);

if (stop_please)
return;
if (result == std::cv_status::timeout)
callback();
}
});
....
void Stop()
{
{
std::lock_guard<std::mutex> lock(MyMutex);
stop_please = true;
}
MyTerminate.notify_all();
MyThread.join();
}

...
private:
bool stop_please = false;
...

通过这些更改,您的计时器应该可以工作,但请注意“[std::condition_variable::wait_for] 由于调度或资源争用延迟,阻塞的时间可能会超过 timeout_duration”,换句话说的 cppreference.com .

point me towards a very simple threaded timer, if there's one already available somewhere.

我不知道标准的 c++ 解决方案,但现代操作系统通常提供这种功能或至少提供可用于构建它的部分。参见 timerfd_create以 Linux 为例。

关于c++ - 简单的线程计时器,请进行健全性检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28883474/

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