python给函数设置超时时间_在 Linux/Mac 下为Python函数添加超时时间
我們在使用 requests 這類網絡請求第三方庫時,可以看到它有一個參數叫做timeout,就是指在網絡請求發出開始計算,如果超過 timeout 還沒有收到返回,就拋出超時異常。(當然存在特殊情況timeout 會失效,請看Timeouts and cancellation for humans*[1] 這篇文章中作者的舉例,我們不考慮這種特殊情況)。
但大家有沒有考慮過,如何為普通的函數設置超時時間?特別是在運行一些數據處理、AI 相關的代碼時,某個函數可能會運行很長時間,我們想實現,在函數運行超過特定的時間時,自動報錯。
例如有這樣一個場景,我寫了一個函數calc_statistic(datas),根據用戶傳入的數據計算某個值。但如果用戶傳入的數據非常大,這個函數就可能運行很長時間。我想設置讓這個函數最多運行10秒鐘。如果10秒還沒有運行完成,就報錯。應該怎么辦呢?
如果你的電腦操作系統是 Linux 或者 macOS,那么 可以使用 signal 來解決。
在公眾號前幾天的文章中,我們介紹了使用signal來接管鍵盤的中斷信號:《一日一技:在 Python 中接管鍵盤中斷信號》,用到的是signal.SIGINT。今天我們要用到的是signal.SIGALRM。
首先我們來看看這個信號的使用方法:
importtime
import signal
def handler(signum, _):
print('定時到!')
raise Exception('定時到了!')
def clac_statistic(datas):
time.sleep(100)
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
clac_statistic('xxx')
運行效果如下圖所示:
首先綁定signal.SIGALRM事件到handler函數中,然后使用signal.alarm(10)延遲10秒發送一個信號。10秒到了以后,函數handler被運行。在函數中拋出了一個異常,導致程序結束。clac_statistic函數原本要運行100秒,但是在10秒以后就停止了,從而實現了函數的超時功能。
基于以上原理,我們實現一個裝飾器,來簡化為不同函數設置超時功能:
importtime
import signal
class FuncTimeoutException(Exception):
pass
def handler(signum, _):
raise FuncTimeoutException('函數定時到了!')
def func_timeout(times=0):
def decorator(func):
if nottimes:
returnfunc
def wraps(*args, **kwargs):
signal.alarm(times)
result = func(*args, **kwargs)
signal.alarm(0) # 函數提前運行完成,取消信號
returnresult
returnwraps
returndecorator
signal.signal(signal.SIGALRM, handler)
我們來試一試測試一下這個函數超時裝飾器。首先測試函數的運行時間小于超時時間時,程序正常運行沒有問題:
再來測試一下函數運行時間超過超時時間的情況:
正常拋出FuncTimeoutException異常。
那我們在實際使用中,可以使用try...except FuncTimeoutException捕獲這個異常,然后實現自定義的處理流程,例如:
try:
clac_statistic(100)
exceptFuncTimeException:
print('該函數運行超時,運行自定義的處理流程')
import contextlib:
withcontextlib.supress(FuncTimeException):
clac_statistic(100)
【編輯推薦】
【責任編輯:華軒 TEL:(010)68476606】
點贊 0
總結
以上是生活随笔為你收集整理的python给函数设置超时时间_在 Linux/Mac 下为Python函数添加超时时间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超出网络bios会话限制_什么是UEFI
- 下一篇: js observer 添加_简单了解4