2016-12-05 65 views
1

我想爲我的項目做一些異步線程。如何中斷異步線程?

我想知道是否有可能通過使用某種方式來完成「任務5」,如中斷。

是否有可能在已經運行的'call_from_async'中更改itv_duration?

#include <iostream> 
#include <future> 
#include <vector> 

using namespace std; 

enum class status{ 
    STATUS_REVICE = 0, 
    STATUS_START = 1, 
    STATUS_COMPLETED = 2, 
    STATUS_CANCELED = 3 
}; 

int called_from_async(std::string taskName, int creationTime, int itv_duration, int itv_start) 
{ 
    cout << "creationTime : " << creationTime << endl; 
    cout << "interval : " << itv_duration << endl; 
    cout << "startTime : " << itv_start << endl; 

    cout << "status : 1 Event Recevied" << endl; 

    bool bExit = false; 
    bool bStart = false; 

    while(!bExit) 
    { 
     if(creationTime > itv_start && !bStart) 
     { 
      bStart = true; 
     } 

     creationTime++; 

     if(bStart) 
     { 
      itv_duration--; 
      if(itv_duration < 0) 
      { 
       bExit = true; 
      } 
     } 

     std::this_thread::sleep_for(std::chrono::seconds(1)); 
    } 

    cout << "status : 3 Event Completed : " << taskName.c_str() << endl; 

    return 1; 
} 

class eventManager 
{ 
public: 
    eventManager() {}; 
    ~eventManager() {}; 

    std::future<int> addTask(std::string taskName, int creationTime, int itv_duration, int itv_start) 
    { 
     return std::async(std::launch::async, called_from_async, taskName, creationTime, itv_duration, itv_start); 
    } 

private: 
}; 

int main() { 

    std::vector<std::future<int>> futures; // place for asyns tasks 

    eventManager evtManager; 

    futures.push_back(std::move(evtManager.addTask("Task 1", 1234560, 20, 1234570))); // will be done as 4th 
    futures.push_back(std::move(evtManager.addTask("Task 2", 1234560, 15, 1234570))); // will be done as third 
    futures.push_back(std::move(evtManager.addTask("Task 3", 1234560, 10, 1234570))); // will be done as second 
    futures.push_back(std::move(evtManager.addTask("Task 4", 1234560, 5, 1234570))); // will be done as first 
    futures.push_back(std::move(evtManager.addTask("Task 5", 1234560, 360, 1234570))); // super long task, but will be done as zero because of cancel event. 

    return 0; 

回答

1

您可以通過引用而不是按值來傳遞持續時間(您想在執行期間更改的變量)。

創建專用變量來處理取消也是一個好主意。在下面的例子中,我使用了一個簡單的bool,但是您可能會考慮一些更花哨的東西,例如std::condition_variable

int called_from_async(std::string taskName, int creationTime, int& itv_duration, int itv_start, bool& cancel) 
{ 
    bool bExit = false; 
    bool bStart = false; 
    while (!bExit && !cancel) 
    { 
     if (creationTime > itv_start && !bStart) 
     { 
      bStart = true; 
     } 

     creationTime++; 

     if (bStart) 
     { 
      if (--itv_duration < 0) 
      { 
       bExit = true; 
      } 
     } 

     std::this_thread::sleep_for(std::chrono::seconds(1)); 
    } 

    std::cout << taskName << std::endl; 

    return 1; 
} 

class eventManager 
{ 
    public: 
    eventManager() { }; 
    ~eventManager() { }; 

    std::future<int> addTask(std::string taskName, int creationTime, int& itv_duration, int itv_start, bool& cancel) 
    { 
     return std::async(std::launch::async, [=, &itv_duration, &cancel]() { return called_from_async(taskName, creationTime, itv_duration, itv_start, cancel); }); 
    } 
}; 

int main() 
{ 

    std::vector<std::future<int>> futures; // place for asyns tasks 

    eventManager evtManager; 

    bool cancel1 = false, cancel5 = false; 
    int shortDuration = 2, longDuration = 360; 
    futures.push_back(std::move(evtManager.addTask("Task 1", 1234560, shortDuration, 1234570, cancel1))); // will be done as 4th 
    //... 
    futures.push_back(std::move(evtManager.addTask("Task 5", 1234560, longDuration, 1234570, cancel5))); // super long task, but will be done as zero because of cancel event. 

    longDuration = 1; 
    //cancel5 = true; 

    //wait for your tasks to finish, so that references are valid 
    //or declare them in the higher scope 

    return 0; 
}