2015-11-10 71 views
0

我想知道是否有一種很好的方法可以在一段時間後終止用C++ 11編寫的進程?如何幹淨地終止C++ 11中的進程?

以我過程我有與運行可能在通信處理被阻止主程序純虛函數run()一個主類。我想我的run()函數被迫在一段時間後(即使被阻塞)和我的主類(以及成員的所有析構函數)的析構函數被完成。

現在我有一個通過回調調用std::terminate一個計時器。

namespace Timer 
{ 
    void start(Duration time, function<void()> task) 
    { 
     thread([time, task]() { 
      this_thread::sleep_for(time); 
      task(); 
     }).detach(); 
    } 
} 
+1

如果'run()'函數不會返回,那麼不能完全結束程序。也許你可以在一個線程中運行'run()',並調用'thread :: detach()':main析構函數會被調用,但我不會稱它爲_clean_。 – rodrigo

+1

我也遇到過這個問題,因爲程序可能會被卡在通信中。我已經添加了心跳meachanism,所以我知道每X秒(在我的情況下,每45秒)一條消息將被接收和發送,然後在一分鐘超時。所以我從來沒有遇到過困擾並等待消息的情況。當然,最糟糕的情況是該程序需要45秒才能關閉,但乾淨了! – Nidhoegger

+0

如果一個(未分離的)線程被阻塞,它不能在沒有先解鎖的情況下被正常終止。您必須通過_e.g._語法來控制這種語法,使用wait/notify或使用'wait_for'或類似方法定期檢查狀態。 – Snps

回答

1

最好的解決辦法是在一個線程包run()

std::thread([&]() 
{ 
    run(); 
    finish.notify_all(); 
}).detach(); 

std::unique_lock<std::mutex> lock(waitFinish); 
finish.wait_for(lock, time); 
1

我猜你是在Linux或其他POSIX系統上。 Event loops和輪詢在C++ 11中不是標準化的,並且需要操作系統特定的東西。

你的事件循環應該永遠不會被阻塞很長一段時間。它應該有一些有限的 - 不要太大 - 超時。在POSIX上,在您的事件循環中使用poll(2),並有合理的超時時間(例如一秒)。或者,使用pipe(內部流程)來觸發事件循環(使其他線程 - 或者甚至是一個信號handler-會write(2)上管,事件循環將輪詢它和read它,可能會停止,因此,從run返回)

另請參閱thisthat的相關提示。

2

真正的解決辦法是處理的原因,而不是症狀:

  • 症狀:run功能永遠不會結束
  • 原因:通信請求永遠不會結束

最通信(輸入)功能是可中斷的,或者有本地超時。如果你的通信例程沒有本地超時,你可以(也許)以一種方式使用alarm Posix調用來包裝它們,它應該乾淨地中斷它們並允許運行函數乾淨地退出。

你只需要注意一點alarm使用信號引擎蓋下的事實,所以你一定不能阻止SIG_ALRM,但你可以用它來安裝存儲地方它已被稱爲信號處理程序。

恕我直言,這將是更簡單,更清潔,並用比std::terminate直接終止程序較好的分離關注。

以上只涉及其中run永遠不會結束的情況下。如果您想限制運行時間,則應在代碼中確定可中斷位置,如果允許運行時間耗盡,則測試您的代碼,並始終在所有可能阻塞的通信IO上放置超時。

+0

你不回答我的問題。 'run()'結束。但可能需要比預期更多的時間。如果太長,我想強制run()完成。它可能被阻塞在通信閱讀或不通過。 – didil