簡體   English   中英

C ++:如何實現任意函數調用的超時?

[英]C++: How to implement a timeout for an arbitrary function call?

不幸的是,我需要調用有時不會在給定時間內終止的庫函數。 有沒有辦法調用該函數,但如果它不在n秒內終止就中止它?

我無法修改函數,所以我不能直接將中止條件放入其中。 我必須在外部為函數添加超時

它可能是一個可能的解決方案,將其作為(提升)線程啟動,然后我可以在一段時間后終止它? 會有類似的東西嗎? 我實際上認為該函數不是線程安全的,但如果我將它作為唯一的單線程運行則無關緊要,對吧? 還有其他(更好的)解決方案嗎?

你可以產生一個boost::thread來調用API:

boost::thread api_caller(::api_function, arg1, arg2);
if (api_caller.timed_join(boost::posix_time::milliseconds(500)))
{
    // API call returned within 500ms
}
else
{
    // API call timed out
}

但是,Boost不允許你殺死工作線程。 在這個例子中,它只是孤兒。

你必須要小心API調用的作用,因為它可能永遠不會釋放它所獲得的資源。

我認為實現這一目標的唯一安全方法是生成一個單獨的沙箱進程,該進程將庫函數作為應用程序的代理調用。 您需要在應用程序和代理之間實現某種類型的IPC。 在讀取IPC回復時實現超時非常簡單。 如果讀取因超時而失敗,則可以安全地終止代理,而不會危及應用程序的運行狀況。

你所說的通常被稱為“看門狗”系統。 監視程序通常是第二個線程,它檢查所有其他線程的狀態。 看門狗通常設置為定期運行。 如果沒有從其他線程收到響應,則監視程序可以通知用戶,或者如果可以安全地(取決於您的應用程序)可以殺死有問題的線程。

線程的問題是在線程終止后你將無法釋放一些資源。 如果您沒有獲得必須釋放的資源,那么請使用線程。

問題是, 如果沒有函數支持的進程內解決方案您最終可能會出現無效狀態。

示例:在進行內存分配時終止線程時,進程堆可能已損壞。

因此,您可以終止呼叫,但之后您還必須終止該過程。 在許多情況下,破壞性副作用的可能性很小,但我不打賭我的計算。

正如Ben Straub建議的那樣,你可以孤立線程:把它放在最低優先級並讓它運行無窮大。 這當然只是一個有限的解決方案:如果線程消耗資源(可能),它們將減慢系統速度,每個進程的線程也有限制(通常是由於線程堆棧的地址空間)。

通常,我更喜歡外部流程解決方案。 一個簡單的模式是這樣的:
將輸入數據寫入文件,以文件作為參數啟動外部進程。 外部進程將進度(如果有)寫入可以監視的磁盤文件,甚至可以允許進程從其開始的位置繼續。 結果將寫入磁盤,父進程可以讀取它們。

當你終止進程時,你仍然需要處理同步對外部資源(如文件)的訪問,以及如何處理被遺棄的mutices,半寫文件等。但它通常是一種強大的解決方案。

“不幸的是,我需要調用有時不會在給定時間內終止的庫函數。有沒有辦法調用函數,但如果它在n秒內沒有終止就會中止它?”

最簡潔的答案是不。 這通常是麻煩...調用本身必須在某個時間終止(實現自己的超時),但是阻塞調用通常是麻煩的(例如gethostbyname()),因為這取決於他們(或系統)超時,而不是你的。

因此,只要有可能,嘗試在必要時使代碼在線程中運行干凈 - 代碼本身必須檢測並處理錯誤。 它可以發送消息和/或設置狀態,以便主(或另一個)線程知道發生了什么。

個人偏好,在高度可用的系統中,我喜歡我的線程經常旋轉(沒有忙碌鎖定),具有特定的超時,調用非阻塞功能,以及准確的退出條件。 一個全局或特定於線程的'done'變量可以實現干凈的退出。

你需要的是一個線程和一個Future Object ,它可以保存函數調用的結果。

有關使用boost的示例,請參閱此處

您需要在超時后檢查未來,如果未設置,則采取相應措施。

使用孤立進程,啟動它並計算執行時間。 如果時間不夠,請調用操作系統將其終止。

如何避免種族沖突。 在這種模式上:

  • 創建一個存儲在args中的文件(當然,所有內容都作為VAL傳遞)。 孤立進程只允許從該文件中讀取數據。

  • 孤立處理輸入數據,創建帶有結果值的輸出文件並關閉它。

  • 只有當一切都完成后,orphan才會刪除輸入文件,這一事實表明主進程已完成工作。

這避免了讀取半寫文件的問題,因為主設備首先注意到輸入文件的缺失,打開以讀取輸出文件,這肯定已經完成(因為在刪除輸入之前關閉,並且OS調用堆棧是順序的)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM