Wug*_*Wug 5 c++ linux sleep pthreads
我正在用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 counter
// reschedule event if necessary
if (e.ShouldReschedule()) eventqueue.push(e);
}
}
QueueUnlock(); // unlock
return; // if threadrunning is set to false, exit
}
Run Code Online (Sandbox Code Playgroud)
这是睡眠功能:
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
}
}
Run Code Online (Sandbox Code Playgroud)
最后,AddEvent:
void Scheduler::AddEvent(Event e)
{
QueueLock();
eventqueue.push(e);
QueueUnlock();
NotifyEventThread();
}
Run Code Online (Sandbox Code Playgroud)
相关变量声明:
bool threadrunning;
priority_queue<Event, vector<Event>, greater<Event> > eventqueue;
pthread_mutex_t queuelock; // QueueLock and QueueUnlock operate on this
pthread_cond_t eventclock;
Run Code Online (Sandbox Code Playgroud)
为了处理泛型事件的问题,每个事件Event包含一个指向抽象类型对象的指针action,子类重写action::DoEvent.从内部调用此方法Event::DoEvent. actions由他们的事件"拥有",即如果事件不再需要重新安排,则会自动删除它们.
你要找的是pthread_cond_t对象pthread_cond_timedwait和pthread_cond_wait功能.您可以创建条件变量isThereAnyTaskToDo并在事件线程中等待它.添加新事件时,您只需唤醒事件线程即可pthread_cond_signal().