2014-12-19 32 views
0

我有一個關於async()函數或任何其他方式來解決我的問題的問題。我向服務器發送指定類型的消息,並等待特定的 響應。 我有功能接收()等待服務器的響應。我在async()中調用這個函數。如何中止async()如果超時已過

示例代碼:

while (true) { 
    future_receive = std::async(std::launch::async, [&] { 
     receive(); 
    }); 

    do { 
     status = future_receive.wait_for(chrono::seconds(timeLimit)); 
     if (status == std::future_status::timeout){ 
      //if timeout, abort async() function 
     } 
    } while (status != std::future_status::ready); 
} 

什麼是我的問題嗎?在這種情況下,如果我得到「超時」,async()函數將起作用, 會等到某些事情發生,即使它永遠不會到來,並且在下一個週期中將再次調用,並且將創建新線程 。如何避免這種情況?

如何在「timeout」超時後中止async()。也許任何其他方式沒有async()來解決這個問題。我只想使用C++的標準庫?

回答

2

異步線程必須配合並檢查它是否應該繼續工作或放棄,沒有可移植的方式來強制它在沒有其合作的情況下停止。

要做到這一點的一種方法是將調用替換爲類似的有超時的調用,並在超時後讓線程放棄,或在超時後檢查標誌以指示是否繼續。

while (true) { 
    std::atomic<bool> stop{false}; 
    future_receive = std::async(std::launch::async, [&] { 
     while (!stop) 
      try_receive(std::chrono::seconds(1)); 
    }); 

    do { 
     status = future_receive.wait_for(chrono::seconds(timeLimit)); 
     if (status == std::future_status::timeout){ 
      stop = true; 
     } 
    } while (status != std::future_status::ready); 
} 

現在異步線程只會阻塞長達一秒鐘,然後將檢查它是否被告知放棄,否則將再次嘗試接收。

如果你願意犧牲便攜性,這樣的事情應該在哪裏std::thread在POSIX線程方面實現的平臺上工作:

while (true) { 
    std::atomic<pthread_t> tid{ pthread_self() }; 
    future_receive = std::async(std::launch::async, [&] { 
     tid = pthread_self(); 
     receive(); 
    }); 

    do { 
     status = future_receive.wait_for(chrono::seconds(timeLimit)); 
     if (status == std::future_status::timeout){ 
      while (tid == pthread_self()) 
      { /* wait for async thread to update tid */ } 
      pthread_cancel(tid); 
     } 
    } while (status != std::future_status::ready); 
} 

這假定有一個pthread取消點某處打電話,這樣pthread_cancel會中斷它。爲了處理異步線程在調用線程超時時甚至還沒有開始運行的情況,有必要在最初的原子中存儲一些已知的值,以及試圖取消它,爲了處理這個問題,我存儲了調用線程的ID,然後在調用pthread_cancel之前一直等到它被更改。)

相關問題