2010-03-20 43 views
5

Trong javascript, hàm ngọt, ngọt này window.setTimeout(func, 1000) ; sẽ không đồng bộ gọi func sau 1000 mili giây.Tương đương với window.setTimeout() cho C++

tôi muốn làm một cái gì đó tương tự như trong C++ (mà không đa luồng), vì vậy tôi đặt cùng một vòng lặp mẫu như:

 
    #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) 
     { 
      c1.func ; // !! doesn't work! 
     } 

     time++; 
     } 
    } 

Làm thế nào tôi có thể làm một cái gì đó giống như công việc này?

+0

Chế độ sleep() có hoạt động với nội dung bạn đang tìm không? –

+0

Không thực sự.Tôi muốn chương trình tiếp tục chạy và gọi lại cho chúng sau – bobobobo

+0

Bạn đang sử dụng nền tảng nào? – avakar

Trả lời

4

Hãy Callback::func loại void (*)(), ví dụ:

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

Bạn có thể gọi hàm theo cách này:

c1.func(); 

Ngoài ra, không bận rộn-chờ đợi. Sử dụng ualarm trên Linux hoặc CreateWaitableTimer trên Windows.

+0

Ah, điểm tốt về 'CreateWaitableTimer' – bobobobo

1

Trong C++, bạn khá hạn chế. Bạn cần một hệ điều hành đa luồng, nơi bạn có thể sử dụng chức năng ngủ (bạn vẫn có thể tiếp tục chạy chương trình với một luồng riêng), hoặc bạn cần một hệ thống nhắn tin, như Windows. Cách khác duy nhất tôi thấy rằng bạn có thể làm điều gì đó là có nhiều cuộc gọi rải rác trong suốt mã gọi một hàm trả về true hoặc false, tùy thuộc vào thời gian đã trôi qua hay chưa. Tất nhiên, hàm này có thể là một cuộc gọi lại, nhưng bạn vẫn cần phải gọi nó theo định kỳ.

+0

Vâng! Đây là những gì tôi đang cố gắng làm. – bobobobo

1

Tôi chỉ đang sửa mã của bạn ở đây, chứ không phải suy nghĩ bên ngoài hộp. Các câu trả lời khác đã đưa ra một số gợi ý cho điều đó.

Đối với loại an toàn hơn, bạn nên khai báo con trỏ callback của bạn như sau:

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

Sau đó, gọi nó là:

c1.func() ; 
+0

Và bạn thưa bạn, đã trả lời câu hỏi! ty. – bobobobo

+0

Hoặc bạn có thể sử dụng (* c1.func)(). Tôi thường sử dụng cú pháp đó với con trỏ đến hàm. Ngoài ra, tôi nghĩ rằng "c1.func = & go" là rõ ràng hơn để đọc. –

+0

Cả hai điểm tốt. – Thomas

0

khác (tốt hơn) câu trả lời sẽ được sử dụng <functional> tiêu đề trong C++ và khai báo hàm như sau:

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

Sau khi C++ 11 xuất hiện và nếu đang sử dụng trình biên dịch được hỗ trợ C++ 11, bạn có thể sử dụng lambda, Chức năng mẫu biến thểchủ đề không đồng bộ để mô phỏng hàm javascript trong C++ dễ dàng.

Đây là mã tôi đã viết cho setTimeout, nó được kiểm tra đầy đủ: định nghĩa

setTimeout Chức năng của:

#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...); 
     }); 
    }; 

Chức năng này chấp nhận đối số biến bằng cách sử dụng c + mẫu variadic 11 của, Mã này có thể chỉ cho bạn cách sử dụng:

#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); 
    } 
+0

Tôi sẽ đề nghị sử dụng 'thread' và' chrono' để ngủ như mô tả ở đây: https://stackoverflow.com/a/10613664/1922713 –

+0

Làm thế nào để bạn gửi hàm thành viên hoặc hàm tĩnh thay vì std :: function thành setTimeOut? –

Các vấn đề liên quan