偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

在 Linux/Mac 下為Python函數(shù)添加超時(shí)時(shí)間

開發(fā) 后端
我們?cè)谑褂?requests 這類網(wǎng)絡(luò)請(qǐng)求第三方庫(kù)時(shí),可以看到它有一個(gè)參數(shù)叫做timeout,就是指在網(wǎng)絡(luò)請(qǐng)求發(fā)出開始計(jì)算,如果超過 timeout 還沒有收到返回,就拋出超時(shí)異常。

 我們?cè)谑褂?requests 這類網(wǎng)絡(luò)請(qǐng)求第三方庫(kù)時(shí),可以看到它有一個(gè)參數(shù)叫做timeout,就是指在網(wǎng)絡(luò)請(qǐng)求發(fā)出開始計(jì)算,如果超過 timeout 還沒有收到返回,就拋出超時(shí)異常。(當(dāng)然存在特殊情況timeout 會(huì)失效,請(qǐng)看Timeouts and cancellation for humans*[1] 這篇文章中作者的舉例,我們不考慮這種特殊情況)。

[[315558]]

但大家有沒有考慮過,如何為普通的函數(shù)設(shè)置超時(shí)時(shí)間?特別是在運(yùn)行一些數(shù)據(jù)處理、AI 相關(guān)的代碼時(shí),某個(gè)函數(shù)可能會(huì)運(yùn)行很長(zhǎng)時(shí)間,我們想實(shí)現(xiàn),在函數(shù)運(yùn)行超過特定的時(shí)間時(shí),自動(dòng)報(bào)錯(cuò)。

例如有這樣一個(gè)場(chǎng)景,我寫了一個(gè)函數(shù)calc_statistic(datas),根據(jù)用戶傳入的數(shù)據(jù)計(jì)算某個(gè)值。但如果用戶傳入的數(shù)據(jù)非常大,這個(gè)函數(shù)就可能運(yùn)行很長(zhǎng)時(shí)間。我想設(shè)置讓這個(gè)函數(shù)最多運(yùn)行10秒鐘。如果10秒還沒有運(yùn)行完成,就報(bào)錯(cuò)。應(yīng)該怎么辦呢?

如果你的電腦操作系統(tǒng)是 Linux 或者 macOS,那么 可以使用 signal 來解決。

在公眾號(hào)前幾天的文章中,我們介紹了使用signal來接管鍵盤的中斷信號(hào):《一日一技:在 Python 中接管鍵盤中斷信號(hào)》,用到的是signal.SIGINT。今天我們要用到的是signal.SIGALRM。

首先我們來看看這個(gè)信號(hào)的使用方法:

 

  1. import time 
  2. import signal 
  3.  
  4.  
  5. def handler(signum, _): 
  6.     print('定時(shí)到!'
  7.     raise Exception('定時(shí)到了!'
  8.  
  9. def clac_statistic(datas): 
  10.     time.sleep(100) 
  11.      
  12.  
  13. signal.signal(signal.SIGALRM, handler) 
  14. signal.alarm(5) 
  15. clac_statistic('xxx'

運(yùn)行效果如下圖所示:

 

首先綁定signal.SIGALRM事件到handler函數(shù)中,然后使用signal.alarm(10)延遲10秒發(fā)送一個(gè)信號(hào)。10秒到了以后,函數(shù)handler被運(yùn)行。在函數(shù)中拋出了一個(gè)異常,導(dǎo)致程序結(jié)束。clac_statistic函數(shù)原本要運(yùn)行100秒,但是在10秒以后就停止了,從而實(shí)現(xiàn)了函數(shù)的超時(shí)功能。

基于以上原理,我們實(shí)現(xiàn)一個(gè)裝飾器,來簡(jiǎn)化為不同函數(shù)設(shè)置超時(shí)功能:

 

  1. import time 
  2. import signal 
  3.  
  4.  
  5. class FuncTimeoutException(Exception): 
  6.     pass 
  7.  
  8. def handler(signum, _): 
  9.     raise FuncTimeoutException('函數(shù)定時(shí)到了!'
  10.  
  11. def func_timeout(times=0): 
  12.     def decorator(func): 
  13.         if not times: 
  14.             return func 
  15.         def wraps(*args, **kwargs): 
  16.             signal.alarm(times) 
  17.             result = func(*args, **kwargs) 
  18.             signal.alarm(0)  # 函數(shù)提前運(yùn)行完成,取消信號(hào) 
  19.             return result 
  20.         return wraps 
  21.     return decorator 
  22.  
  23. signal.signal(signal.SIGALRM, handler) 

我們來試一試測(cè)試一下這個(gè)函數(shù)超時(shí)裝飾器。首先測(cè)試函數(shù)的運(yùn)行時(shí)間小于超時(shí)時(shí)間時(shí),程序正常運(yùn)行沒有問題:

 

再來測(cè)試一下函數(shù)運(yùn)行時(shí)間超過超時(shí)時(shí)間的情況:

正常拋出FuncTimeoutException異常。

那我們?cè)趯?shí)際使用中,可以使用try...except FuncTimeoutException捕獲這個(gè)異常,然后實(shí)現(xiàn)自定義的處理流程,例如:

 

  1. try: 
  2.     clac_statistic(100) 
  3. except FuncTimeException: 
  4.     print('該函數(shù)運(yùn)行超時(shí),運(yùn)行自定義的處理流程'

當(dāng)然你如果想直接跳過這個(gè)異常也沒問題,參考《一日一技:不使用 try...except 掩蓋一些已知異常》

 

  1. import contextlib: 
  2. with contextlib.supress(FuncTimeException): 
  3.     clac_statistic(100) 

 

責(zé)任編輯:華軒 來源: 未聞Code
相關(guān)推薦

2009-03-05 09:18:13

LinuxUbuntuMySQL

2009-07-06 18:09:18

linuxApache密碼

2023-03-01 10:42:58

gRPC服務(wù)端設(shè)置

2016-09-19 09:15:49

Windows 10鎖屏超時(shí)

2025-02-12 08:47:07

SpringAPI接口

2023-10-12 08:54:20

Spring事務(wù)設(shè)置

2024-09-10 09:05:12

SpringREST并發(fā)

2023-08-14 21:54:41

OptionsFeign接口

2023-11-29 07:40:12

分布式

2019-07-22 15:20:40

Linux系統(tǒng)病毒

2024-02-28 12:41:00

源碼內(nèi)核參數(shù)

2009-04-15 20:52:37

Linux設(shè)置IPMAC綁定

2010-03-03 17:14:10

Linux路由設(shè)置ip

2010-04-21 13:21:24

Oracle時(shí)間

2014-05-22 15:38:27

Android消息處理機(jī)制Looper

2024-03-29 00:00:00

JSAPI網(wǎng)絡(luò)

2025-01-15 00:00:10

2009-12-09 10:16:39

ibmdwLotus

2011-11-17 09:17:04

開發(fā)LinuxMacOS

2022-03-03 13:22:52

LinuxKDE PlasmaKDE
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)