Как создать события таймера с помощью C ++ 11?

Как создать события таймера с помощью C ++ 11?

Мне нужно что-то вроде: «Позвони мне через 1 секунду».

Есть ли библиотека?

Сделал простую реализацию того, что, как я считаю, является тем, чего вы хотите достичь. Вы можете использовать class later со следующими аргументами:

  • int (миллисекунды ждать до запуска кода)
  • bool (если true, он мгновенно возвращается и запускает код после указанного времени в другом streamе)
  • переменные аргументы (именно то, что вы хотите использовать для std :: bind )

Вы можете изменить std::chrono::milliseconds на std::chrono::nanoseconds или microseconds для еще большей точности и добавить второй цикл int и for, чтобы указать, сколько раз запускать код.

Здесь вы идете, наслаждайтесь:

 #include  #include  #include  #include  class later { public: template  later(int after, bool async, callable&& f, arguments&&... args) { std::function::type()> task(std::bind(std::forward(f), std::forward(args)...)); if (async) { std::thread([after, task]() { std::this_thread::sleep_for(std::chrono::milliseconds(after)); task(); }).detach(); } else { std::this_thread::sleep_for(std::chrono::milliseconds(after)); task(); } } }; void test1(void) { return; } void test2(int a) { printf("%i\n", a); return; } int main() { later later_test1(1000, false, &test1); later later_test2(1000, false, &test2, 101); return 0; } 

Выходы через две секунды:

 101 

Если вы находитесь в Windows, вы можете использовать функцию CreateThreadpoolTimer для планирования обратного вызова без необходимости беспокоиться об управлении streamами и без блокировки текущего streamа.

 template static void __stdcall timer_fired(PTP_CALLBACK_INSTANCE, PVOID context, PTP_TIMER timer) { CloseThreadpoolTimer(timer); std::unique_ptr callable(reinterpret_cast(context)); (*callable)(); } template  void call_after(T callable, long long delayInMs) { auto state = std::make_unique(std::move(callable)); auto timer = CreateThreadpoolTimer(timer_fired, state.get(), nullptr); if (!timer) { throw std::runtime_error("Timer"); } ULARGE_INTEGER due; due.QuadPart = static_cast(-(delayInMs * 10000LL)); FILETIME ft; ft.dwHighDateTime = due.HighPart; ft.dwLowDateTime = due.LowPart; SetThreadpoolTimer(timer, &ft, 0 /*msPeriod*/, 0 /*msWindowLength*/); state.release(); } int main() { auto callback = [] { std::cout << "in callback\n"; }; call_after(callback, 1000); std::cin.get(); } 

Это код, который у меня есть до сих пор:

Я использую VC ++ 2012 (без вариационных шаблонов)

 //header #include  #include  #include  #include  #include  #include  #include  template class TimerThread { typedef std::chrono::high_resolution_clock clock_t; struct TimerInfo { clock_t::time_point m_TimePoint; T m_User; template  TimerInfo(clock_t::time_point tp, TArg1 && arg1) : m_TimePoint(tp) , m_User(std::forward(arg1)) { } template  TimerInfo(clock_t::time_point tp, TArg1 && arg1, TArg2 && arg2) : m_TimePoint(tp) , m_User(std::forward(arg1), std::forward(arg2)) { } }; std::unique_ptr m_Thread; std::vector m_Timers; std::mutex m_Mutex; std::condition_variable m_Condition; bool m_Sort; bool m_Stop; void TimerLoop() { for (;;) { std::unique_lock lock(m_Mutex); while (!m_Stop && m_Timers.empty()) { m_Condition.wait(lock); } if (m_Stop) { return; } if (m_Sort) { //Sort could be done at insert //but probabily this thread has time to do std::sort(m_Timers.begin(), m_Timers.end(), [](const TimerInfo & ti1, const TimerInfo & ti2) { return ti1.m_TimePoint > ti2.m_TimePoint; }); m_Sort = false; } auto now = clock_t::now(); auto expire = m_Timers.back().m_TimePoint; if (expire > now) //can I take a nap? { auto napTime = expire - now; m_Condition.wait_for(lock, napTime); //check again auto expire = m_Timers.back().m_TimePoint; auto now = clock_t::now(); if (expire <= now) { TimerCall(m_Timers.back().m_User); m_Timers.pop_back(); } } else { TimerCall(m_Timers.back().m_User); m_Timers.pop_back(); } } } template friend void CreateTimer(TimerThread& timerThread, int ms, TArg1 && arg1); template friend void CreateTimer(TimerThread& timerThread, int ms, TArg1 && arg1, TArg2 && arg2); public: TimerThread() : m_Stop(false), m_Sort(false) { m_Thread.reset(new std::thread(std::bind(&TimerThread::TimerLoop, this))); } ~TimerThread() { m_Stop = true; m_Condition.notify_all(); m_Thread->join(); } }; template void CreateTimer(TimerThread& timerThread, int ms, TArg1 && arg1) { { std::unique_lock lock(timerThread.m_Mutex); timerThread.m_Timers.emplace_back(TimerThread::TimerInfo(TimerThread::clock_t::now() + std::chrono::milliseconds(ms), std::forward(arg1))); timerThread.m_Sort = true; } // wake up timerThread.m_Condition.notify_one(); } template void CreateTimer(TimerThread& timerThread, int ms, TArg1 && arg1, TArg2 && arg2) { { std::unique_lock lock(timerThread.m_Mutex); timerThread.m_Timers.emplace_back(TimerThread::TimerInfo(TimerThread::clock_t::now() + std::chrono::milliseconds(ms), std::forward(arg1), std::forward(arg2))); timerThread.m_Sort = true; } // wake up timerThread.m_Condition.notify_one(); } //sample #include  #include  void TimerCall(int i) { std::cout << i << std::endl; } int main() { std::cout << "start" << std::endl; TimerThread timers; CreateTimer(timers, 2000, 1); CreateTimer(timers, 5000, 2); CreateTimer(timers, 100, 3); std::this_thread::sleep_for(std::chrono::seconds(5)); std::cout << "end" << std::endl; } 

Асинхронное решение от Эдварда:

  • Создать новую тему
  • спать в этой нити
  • выполнить задачу в этом streamе

просто и может просто работать на вас.

Я также хотел бы дать более продвинутую версию, которая имеет следующие преимущества:

  • нет накладных расходов на запуск нитей
  • только один дополнительный stream на каждый процесс, необходимый для обработки всех заданий по времени

Это может быть особенно полезно в крупных проектах программного обеспечения, где у вас много задач, выполняемых повторно в вашем процессе, и вы заботитесь об использовании ресурсов (streamах), а также о служебных нагрузках на запуск.

Идея: иметь один stream услуг, который обрабатывает все зарегистрированные заданные сроки. Используйте для этого повышение io_service.

Код похож на: http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/tutorial/tuttimer2/src.html

 #include  #include  #include  int main() { boost::asio::io_service io; boost::asio::deadline_timer t(io, boost::posix_time::seconds(1)); t.async_wait([](const boost::system::error_code& /*e*/){ printf("Printed after 1s\n"); }); boost::asio::deadline_timer t2(io, boost::posix_time::seconds(1)); t2.async_wait([](const boost::system::error_code& /*e*/){ printf("Printed after 1s\n"); }); // both prints happen at the same time, // but only a single thread is used to handle both timed tasks // - namely the main thread calling io.run(); io.run(); return 0; } 
  • Использование libstdc ++ скомпилированных библиотек с помощью clang ++ -stdlib = libc ++
  • Почему C ++ 11 не поддерживает назначенные списки инициализаторов как C99?
  • Как я могу расширить кортеж в аргументы функции вариационной матрицы?
  • Что такое std :: prom?
  • c ++ доступ к статическим членам с использованием нулевого указателя
  • Всегда ли перемещаемый вектор всегда пуст?
  • Неопределенная ссылка на статический constexpr char
  • Отключить ошибки затмения (которые на самом деле не являются ошибками)
  • Сколько стоит слишком много с ключевым словом C ++ 11 auto?
  • void_t "может реализовать концепции"?
  • push_back vs emplace_back
  • Interesting Posts

    Возможные расположения для последовательности / параметров набора изображений для streamа H.264

    С трудом использовать ASP.NET MVC ViewBag и DropDownListfor

    Android: Как вернуть async JSONObject из метода с помощью Volley?

    Bluetooth гарнитуры и появляется в звуковых устройствах, но отображается как отключено?

    JQuery-Mobile разворачивается развернуть / свернуть событие

    Как перейти от общедоступной сети к частной сети

    Как интернационализировать веб-приложение Java?

    У XSLT есть функция Split ()?

    ASP.NET MVC – аутентифицировать пользователей в Active Directory, но требует ввода имени пользователя и пароля

    Обнаружить измененное текстовое поле ввода

    Есть ли ограничение, которое ограничивает мой общий метод численными типами?

    Какова максимальная типичная скорость с приводом USB2.0?

    Выполните команду в командной строке с помощью excel VBA

    Java: двумерный массив хранится в порядке столбцов или строк?

    сюжетный график в R

    Давайте будем гением компьютера.