Эквивалент window.setTimeout () для C ++ - PullRequest
7 голосов
/ 21 марта 2010

В javascript есть эта сладкая, приятная функция window.setTimeout( func, 1000 ) ;, которая будет асинхронно вызывать func через 1000 мс.

Я хочу сделать что-то подобное в C ++ ( без многопоточности ), поэтому я собрал примерный цикл, например:

    #include <stdio.h>

    struct Callback
    {
      // The _time_ this function will be executed.
      double execTime ;

      // The function to execute after execTime has passed
      void* func ;
    } ;

    // Sample function to execute
    void go()
    {
      puts( "GO" ) ;
    }

    // Global program-wide sense of time
    double time ;

    int main()
    {
      // start the timer
      time = 0 ;

      // Make a sample callback
      Callback c1 ;
      c1.execTime = 10000 ;
      c1.func = go ;

      while( 1 )
      {
        // its time to execute it
        if( time > c1.execTime )
        {
          <b>c1.func ; // !! doesn't work!</b>
        }

        time++;
      }
    }

Как я могу сделать что-то вроде этой работы?

Ответы [ 5 ]

7 голосов
/ 07 декабря 2013

После выхода C ++ 11, и если вы используете компилятор, поддерживаемый c ++ 11, вы можете использовать лямбда , шаблонную функцию variadic и асинхронный поток для имитации функции JavaScript в C ++ легко.

Вот код, который я написал для setTimeOut, он полностью протестирован:

Определение функции setTimeOut:

    #include <windows.h>//different header file in linux
    #include <future>
    using namespace std;

    template <typename... ParamTypes>
    void setTimeOut(int milliseconds,std::function<void(ParamTypes...)> func,ParamTypes... parames)
    {   
        std::async(std::launch::async,[=]()
        {       
            Sleep(milliseconds);
            func(parames...); 
        });
     };

Эта функция принимает переменные аргументы, используя переменную c + 11шаблон, код может показать вам, как его использовать:

    #include <iostream>
    #include <thread>
    #include <string>
    #include <functional>
    #include <windows.h>

    #include <future>
    using namespace std;
    int main() 
    {
        std::mutex locker;
        std::function<void()> func1 = [&]()
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 1 is trigged:" << "   no parameter" << std::endl;
            lk.unlock();
        };      
        std::function<void(int)> func2 = [&](int param)
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 2 is trigged:" << "   int: " << param <<std::endl;
            lk.unlock();
        };
        std::function<void(int,std::string)> func3 = [&](int param1,std::string param2)
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 3 is trigged:" << "   int: " << param1 << ";  string: " << param2 << std::endl;
            lk.unlock();
        };

        for(int index=0;index<100;index++)
        {
            std::unique_lock<std::mutex> lk1(locker);
            std::cout << "set timer for func  1" << std::endl;
            lk1.unlock();
            setTimeOut<>(1000,func1);

            std::unique_lock<std::mutex> lk2(locker);
            std::cout << "set timer for func  2" << std::endl;
            lk2.unlock();
            setTimeOut<int>(2000,func2,10000);

            std::unique_lock<std::mutex> lk3(locker);
            std::cout << "set timer for func  3" << std::endl;
            lk3.unlock();
            setTimeOut<int,std::string>(5000,func3,10000,"ddddd");
        }
        Sleep(10000000);
    }
5 голосов
/ 21 марта 2010

Марка Callback::func типа void (*)(), т.е.

struct Callback
{
    double execTime;
    void (*func)();
};

Вы можете вызвать функцию следующим образом:

c1.func();

Кроме того, не заняты - подождите. Используйте ualarm в Linux или CreateWaitableTimer в Windows.

1 голос
/ 21 марта 2010

Я только исправляю твой код здесь, не думая нестандартно. Другие ответы уже дали некоторые указания на это.

Для большей безопасности типов вы должны объявить указатель обратного вызова следующим образом:

  // The function to execute after execTime has passed
  void (*func)() ;

Затем назовите его так:

  c1.func() ;
1 голос
/ 21 марта 2010

Сам по себе C ++ довольно ограничен. Вам нужна либо многопоточная ОС, где вы могли бы использовать функцию сна (вы все еще можете запустить программу с отдельным потоком), либо вам нужна система обмена сообщениями, например Windows.

Единственный способ увидеть, что вы можете что-то сделать, - это разбросать множество вызовов по всему коду, который вызывает функцию, которая возвращает истину или ложь, в зависимости от того, истекло ли время. Функция, конечно, может быть обратным вызовом, но вам все равно придется периодически вызывать ее.

0 голосов
/ 14 декабря 2011

Другой (лучший) ответ - использовать заголовок <functional> в C ++ и объявить функцию следующим образом:

#include <functional>

function<void ()> func ;

// assign like
func = go ; //go is a function name that accepts 0 parameters
// and has return type void

// exec like
func() ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...