我正在用C++编写程序。我注意到,它获得了许多线程,它们的目的是定期执行某项操作,其中有3或4个线程。我决定通过编写一个调度程序服务来重构,以便使用这些线程的其他地方可以预订该服务,这应该将我随时运行的额外事件线程的数量减少到一个。
我还没有使用此代码的代码。在开始编写之前,我想知道是否有可能,并获得有关我的设计的一些反馈。我要完成的任务的简要说明是这样的:
添加事件
事件线程主循环
我已经进行了一些研究,并且知道可以中断睡眠线程,并且我相信,只要防止同时访问事件队列,就不应有任何危险行为。我以为唤醒线程是有可能的,在某些情况下,java的Thread的sleep()调用会引发InterruptedException,并且除非它不依赖于操作系统的基础sleep调用,否则它一定会成为可能。
谁能评论我的方法?这是我最好不要重新发明的轮子吗?具体来说,如何中断正在hibernate的线程,以便在下一条指令处恢复执行,并有可能从被中断的线程中检测到这一点?
关于升压的注意事项
我敢打赌,您可以编写一个带有boost的调度程序,但是由于缺少更好的说法,它可以在一台机器上编译并运行。我之前已经编译了boost程序,并且每个引入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 counter // reschedule event if necessary if (e.ShouldReschedule()) eventqueue.push(e); } } QueueUnlock(); // unlock return; // if threadrunning is set to false, exit }
这是hibernate功能:
void Scheduler::SleepUntilNextEvent() { bool empty = eventqueue.empty(); // check if empty if (empty) { pthread_cond_wait(&eventclock, &queuelock); // wait forever if empty } else { timespec t = // get absolute time of wakeup Bottime::GetMillisAsTimespec(eventqueue.top().Countdown() + Bottime::GetCurrentTimeMillis()); pthread_cond_timedwait(&eventclock, &queuelock, &t); // sleep until event } }
最后,AddEvent:
void Scheduler::AddEvent(Event e) { QueueLock(); eventqueue.push(e); QueueUnlock(); NotifyEventThread(); }
相关变量声明:
bool threadrunning; priority_queue<Event, vector<Event>, greater<Event> > eventqueue; pthread_mutex_t queuelock; // QueueLock and QueueUnlock operate on this pthread_cond_t eventclock;
为了处理一般事件,每个事件都Event包含一个指向抽象类型对象的指针,该对象的action子类重写action::DoEvent。从内部调用此方法Event::DoEvent。 actions由其事件“拥有”,即,如果不再需要重新安排事件,它们将被自动删除。
Event
action
action::DoEvent
Event::DoEvent
actions
您正在寻找的是pthread_cond_t对象pthread_cond_timedwait和pthread_cond_wait功能。您可以创建条件变量 isThereAnyTaskToDo 并在事件线程中等待它。添加新事件后,只需使用唤醒事件线程pthread_cond_signal()。
pthread_cond_t
pthread_cond_timedwait
pthread_cond_wait
pthread_cond_signal()