Простой многопоточный планировщик времени


Вот наспех сделанный планировщик времени, чтобы удовлетворить мои требования и даже для моих будущих проектов. Это работает, как задумано, но я хочу еще улучшить . Я самоучка, энтузиаст, и довольно слаб как юрист язык.

Этот планировщик должен уметь планировать задачи, которые будут выполнены задания, в нужный экземпляр. Надо договориться о времени-очков в хронологическом(//todo в граничное условие) порядке.

typedef std::function<void(void)> func;
typedef std::chrono::system_clock::time_point time_point;
std::map<time_point, func> schedule;

int main()
{
    schedule.insert(make_pair(std::chrono::system_clock::now() + std::chrono::seconds(4s), []() { std::cout << " Slow first \n"; }));
    schedule.insert(make_pair(std::chrono::system_clock::now() + std::chrono::seconds(3s), []() { std::cout << " Medium second \n"; }));
    thread t([]()
    {
        while (!schedule.empty())
        {
            if (chrono::system_clock::now() >= (schedule.begin())->first)
            {
                (schedule.begin())->second();
                schedule.erase(schedule.begin());
            }
            this_thread::sleep_for(chrono::milliseconds(1ms));
        }
    });
    schedule.insert(make_pair(std::chrono::system_clock::now() + std::chrono::milliseconds(500ms), []() { std::cout << " Impatience third \n"; }));
    std::cout << " main is waiting for the thread to end already \n";
    t.join();
    return 0;
}


188
1
задан 17 марта 2018 в 02:03 Источник Поделиться
Комментарии
1 ответ

Я заметил, что очень плохо (анти-)шаблон, который вы используете. Вы опрашиваете. "Просыпаюсь часто, чтобы проверить, нет ли работы, если не спи". Поток требует, чтобы его будили каждые 1мс или так. Это вызовет большую нагрузку на ОС поток планировщика и снижению производительности. Оно также предотвращает ваш процессор в спящий режим (режим пониженного энергопотребления), поэтому потребление энергии и тепла вашего процессора будет значительно увеличить.

Что вы должны сделать вместо этого, чтобы иметь свой поток спать до следующего раза, что событие запланировано. Убедитесь, что ваш сон имеет способ быть прервана в случае, если новое событие приходит. Искать "переменных состояния". (#include <condition_variable>)

Во-вторых, вы лечите std::map как будто это потокобезопасными. Это не так. Если основной поток изменяет map в то же мгновение, что планировщик потоков проверяет его, плохие вещи могут случиться. Жуткие глюки, которые происходят периодически и невозможно воспроизвести или следов. Вы должны использовать потокобезопасные структуры данных (или контроль доступа с использованием какой-то механизм блокировки, который вам все равно нужен для переменной состояния) если вы собираетесь разделить его между несколькими потоками.

Позвольте мне сделать это ясно: не подвергайте фактический std::map в случае провайдеров. Все должно пройти методов, которые обеспечивают надлежащее блокировка объекта (и разбудить-нить если надо).

Если вы хотите быть в состоянии расширить это, вы действительно должны сделать это свой собственный class С определенного интерфейса, тогда можно определить реализацию, как вы пожелаете. Операции могут быть: добавить событие, удалить событие, планирование, планирование выкл, список всех событий, перечислять события по одному, времени изменить события, изменить события, удалить все события.

4
ответ дан 17 марта 2018 в 06:03 Источник Поделиться