假设我有一个线程,应该定期执行一些任务,但这个时期是 每小时6次每小时12次(每5分钟),我经常看到用一个is_running标志控制线程循环的代码,每个循环检查一次,如下所示:
std::atomic<bool> is_running;
void start()
{
is_running.store(true);
std::thread { thread_function }.detach();
}
void stop()
{
is_running.store(false);
}
void thread_function()
{
using namespace std::literals;
while (is_running.load())
{
// do some task...
std::this_thread::sleep_for(5min);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果stop()函数被调用,比如说,start()在线程处于活动状态之后1毫秒,直到它唤醒299999毫秒,检查标志并死掉.
我的理解是否正确?如何避免保持活着(但是睡觉)应该已经结束的线程?到目前为止,我最好的方法如下:
void thread_function()
{
using namespace std::literals;
while (is_running.load())
{
// do some task...
for (unsigned int b = 0u, e = 1500u; is_running.load() && (b != e); ++b)
{
// 1500 * 200 = 300000ms = 5min …Run Code Online (Sandbox Code Playgroud) 我正在用C++编写程序.我注意到它正在获得许多线程,其目的是每隔一段时间做一些事情,其中有3个或4个.我决定通过编写一个调度程序服务来重构,使用这些线程的其他地方可以订阅,这应该减少我在任何时候运行的额外事件线程的数量.
我还没有任何使用它的代码; 在我开始编写它之前,我想知道它是否可行,并获得一些关于我的设计的反馈.我想要完成的内容的简要说明如下:
添加活动
事件线程主循环
我已经做了一些研究,并且知道可以中断一个休眠线程,我相信只要防止同时访问事件队列,就不应该有任何危险的行为.我想,唤醒一个线程是可能的,java的Thread的sleep()调用在某些情况下抛出一个InterruptedException,除非它不依赖于操作系统的底层睡眠调用,否则它必须以某种方式.
任何人都可以评论我的方法吗?这是一个轮子,我最好不要重新发明?具体来说,如何中断睡眠线程,以便在下一条指令处恢复执行,是否可以从被中断的线程中检测到这一点?
关于提升的说明
我敢打赌你可以编写一个带有提升的调度程序,但是这会编译并在一台机器上运行,因为缺少一个更好的短语,一堆垃圾.我之前已经编译过boost程序,每个提升程序的文件通常需要30秒才能编译.如果我能避免这种恼人的发展障碍,我非常愿意.
这是我生产的代码有效.它已经过初步测试,但已经妥善处理了具有不同延迟的单个和重复事件.
这是事件线程的正文:
void Scheduler::RunEventLoop()
{
QueueLock(); // lock around queue access
while (threadrunning)
{
SleepUntilNextEvent(); // wait for something to happen
while (!eventqueue.empty() && e.Due())
{ // while pending due events exist
Event e = eventqueue.top();
eventqueue.pop();
QueueUnlock(); // unlock
e.DoEvent(); // perform the event
QueueLock(); // lock around queue access
e.Next(); // decrement repeat …Run Code Online (Sandbox Code Playgroud)