【问题标题】:Equivalent to window.setTimeout() for C++等效于 C++ 的 window.setTimeout()
【发布时间】:2011-01-29 21:56:44
【问题描述】:

在 javascript 中有这个甜蜜的函数 window.setTimeout( func, 1000 ) ;,它将在 1000 毫秒后异步调用 func

我想在 C++ 中做类似的事情(没有多线程),所以我整理了一个示例循环,例如:

#include 结构回调 { // _time_ 这个函数将被执行。 双执行时间; // execTime 过后要执行的函数 无效*函数; } ; // 要执行的示例函数 无效的去() { 放(“去”); } // 全局程序范围的时间感 双倍时间 ; 主函数() { // 启动定时器 时间 = 0 ; // 做一个示例回调 回调 c1 ; c1.execTime = 10000 ; c1.func = 去; 而(一) { // 是时候执行它了 如果(时间> c1.execTime) { c1.func ; // !!不工作! } 时间++; } }

我怎样才能做出这样的事情?

【问题讨论】:

  • sleep() 函数是你要找的东西吗?
  • 并非如此。我希望程序继续运行并稍后调用它们
  • 真的不应该依赖平台。
  • 问题 真的 是关于那里的粗体线,c1.func 确实 not 调用该函数,它似乎没有做任何事情!
  • 现在回想起来,天哪,我太菜鸟了。括号,括号!

标签: c++ function execution void-pointers


【解决方案1】:

C++11出来后,如果你使用的是c++11支持的编译器,可以使用lambda可变模板函数异步线程轻松模拟c++中的javascript函数。

这是我为 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);
    }

【讨论】:

  • 我建议使用 threadchrono 进行睡眠,如下所述:stackoverflow.com/a/10613664/1922713
  • 如何将成员函数或静态函数而不是 std::function 发送到 setTimeOut ?
【解决方案2】:

使Callback::func 类型为void (*)(),即

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

你可以这样调用函数:

c1.func();

另外,不要忙着等待。在 Linux 上使用 ualarm 或在 Windows 上使用 CreateWaitableTimer

【讨论】:

    【解决方案3】:

    仅在 C++ 中,您的能力非常有限。您需要一个多线程操作系统,您可以在其中使用睡眠功能(您仍然可以让程序继续使用单独的线程运行),或者您需要一个消息传递系统,如 Windows。

    我看到您可以做某事的唯一另一种方法是在代码中分散大量调用,这些调用调用返回 true 或 false 的函数,具体取决于时间是否已过。当然,该函数可以是回调,但您仍需要定期调用它。

    【讨论】:

    • 是的!这就是我想要做的。
    【解决方案4】:

    我只是在这里修复您的代码,而不是跳出框框思考。其他答案已经给出了一些指示。

    为了更好的类型安全,你应该如下声明你的回调指针:

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

    然后,将其称为:

      c1.func() ;
    

    【讨论】:

    • 或者你可以使用 (* c1.func)()。我通常将该语法与指向函数的指针一起使用。另外,我认为“c1.func = & go”更易读。
    【解决方案5】:

    另一个(更好的)答案是在 C++ 中使用 &lt;functional&gt; 标头,并像这样声明函数:

    #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() ;
    

    【讨论】:

      猜你喜欢
      • 2012-02-18
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      相关资源
      最近更新 更多