I am writing a program in C ++. I noticed that he receives several streams, the purpose of which is to do something at intervals, there are 3 or 4. I decided to reorganize by writing a scheduler service into which other places that use these streams can subscribe, which should reduce the number of additional streams events that I started at any time, just one.
I don't have code that hasn't used it yet; before I start writing, I would like to know, if possible, and get some feedback on my design. A brief description of what I would like to do is the following:
To add an event
- Caller provides event and schedule
- The schedule provides the next occurrence of the event. A few words
- (event, schedule) is added to the event queue
- interrupt a sleeping stream of events (i.e. wake it up)
The main event flow loop
- try to get the next event in the event queue
- If there is no pending event, go straight to 4
- Get the time during which the next event should occur.
- Sleep until the next event (or forever if there is no pending event)
- If the dream was interrupted for any reason, go back to 1
- If the dream is successful, execute the current event.
- Refresh queue (delete event, reinsert if it is a recurring event)
- Go to 1
, , , , . , , java Thread sleep() , , , - .
- ? , ? , , , , ?
, boost, , , - , . , , , 30 . , .
- [ ]
, , . , , .
:
void Scheduler::RunEventLoop()
{
QueueLock();
while (threadrunning)
{
SleepUntilNextEvent();
while (!eventqueue.empty() && e.Due())
{
Event e = eventqueue.top();
eventqueue.pop();
QueueUnlock();
e.DoEvent();
QueueLock();
e.Next();
if (e.ShouldReschedule()) eventqueue.push(e);
}
}
QueueUnlock();
return;
}
:
void Scheduler::SleepUntilNextEvent()
{
bool empty = eventqueue.empty();
if (empty)
{
pthread_cond_wait(&eventclock, &queuelock);
}
else
{
timespec t =
Bottime::GetMillisAsTimespec(eventqueue.top().Countdown() +
Bottime::GetCurrentTimeMillis());
pthread_cond_timedwait(&eventclock, &queuelock, &t);
}
}
, 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;
pthread_cond_t eventclock;
, Event action, whos action::DoEvent. Event::DoEvent. actions "" , , .