日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)Python教程:signal—-設(shè)置異步事件處理程序

signal —- 設(shè)置異步事件處理程序


該模塊提供了在 python 中使用信號處理程序的機制。

創(chuàng)新互聯(lián)建站2013年至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元弋陽做網(wǎng)站,已為上家服務(wù),為弋陽各地企業(yè)和個人服務(wù),聯(lián)系電話:028-86922220

一般規(guī)則

signal.signal() 函數(shù)允許定義在接收到信號時執(zhí)行的自定義處理程序。少量的默認處理程序已經(jīng)設(shè)置: SIGPIPE 被忽略(因此管道和套接字上的寫入錯誤可以報告為普通的 Python 異常)以及如果父進程沒有更改 SIGINT ,則其會被翻譯成 KeyboardInterrupt 異常。

一旦設(shè)置,特定信號的處理程序?qū)⒈3职惭b,直到它被顯式重置( Python 模擬 BSD 樣式接口而不管底層實現(xiàn)),但 SIGCHLD 的處理程序除外,它遵循底層實現(xiàn)。

On WebAssembly platforms wasm32-emscripten and wasm32-wasi, signals are emulated and therefore behave differently. Several functions and signals are not available on these platforms.

執(zhí)行 Python 信號處理程序

Python 信號處理程序不會在低級( C )信號處理程序中執(zhí)行。相反,低級信號處理程序設(shè)置一個標志,告訴 virtual machine 稍后執(zhí)行相應(yīng)的 Python 信號處理程序(例如在下一個 bytecode 指令)。這會導致:

  • 捕獲同步錯誤是沒有意義的,例如 SIGFPE 或 SIGSEGV ,它們是由 C 代碼中的無效操作引起的。Python 將從信號處理程序返回到 C 代碼,這可能會再次引發(fā)相同的信號,導致 Python 顯然的掛起。 從Python 3.3開始,你可以使用 faulthandler 模塊來報告同步錯誤。

  • 純 C 中實現(xiàn)的長時間運行的計算(例如在大量文本上的正則表達式匹配)可以在任意時間內(nèi)不間斷地運行,而不管接收到任何信號。計算完成后將調(diào)用 Python 信號處理程序。

  • 如果處理句柄引發(fā)了異常,它將在主線程中“憑空”被引發(fā)。 請參閱 下面的注釋 討論相關(guān)細節(jié)。

信號與線程

Python 信號處理程序總是會在主 Python 主解釋器的主線程中執(zhí)行,即使信號是在另一個線程中接收的。 這意味著信號不能被用作線程間通信的手段。 你可以改用 threading 模塊中的同步原語。

此外,只有主解釋器的主線程才被允許設(shè)置新的信號處理程序。

模塊內(nèi)容

在 3.5 版更改: signal (SIG*), handler (SIG_DFL, SIG_IGN) and sigmask (SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK) related constants listed below were turned into enums (Signals, Handlers and Sigmasks respectively). getsignal(), pthread_sigmask(), sigpending() and sigwait() functions return human-readable enums as Signals objects.

The signal module defines three enums:

class signal.Signals

enum.IntEnum collection of SIG* constants and the CTRL_* constants.

3.5 新版功能.

class signal.Handlers

enum.IntEnum collection the constants SIG_DFL and SIG_IGN.

3.5 新版功能.

class signal.Sigmasks

enum.IntEnum collection the constants SIG_BLOCK, SIG_UNBLOCK and SIG_SETMASK.

可用性: Unix。

3.5 新版功能.

在 signal 模塊中定義的變量是:

signal.SIG_DFL

這是兩種標準信號處理選項之一;它只會執(zhí)行信號的默認函數(shù)。 例如,在大多數(shù)系統(tǒng)上,對于 SIGQUIT 的默認操作是轉(zhuǎn)儲核心并退出,而對于 SIGCHLD 的默認操作是簡單地忽略它。

signal.SIG_IGN

這是另一個標準信號處理程序,它將簡單地忽略給定的信號。

signal.SIGABRT

來自 abort(3)) 的中止信號。

signal.SIGALRM

來自 alarm(2)) 的計時器信號。

可用性: Unix。

signal.SIGBREAK

來自鍵盤的中斷 (CTRL + BREAK)。

可用性: Windows。

signal.SIGBUS

總線錯誤 (非法的內(nèi)存訪問)。

可用性: Unix。

signal.SIGCHLD

子進程被停止或終結(jié)。

可用性: Unix。

signal.SIGCLD

SIGCHLD 的別名。

signal.SIGCONT

如果進程當前已停止則繼續(xù)執(zhí)行它

可用性: Unix。

signal.SIGFPE

浮點異常。 例如除以零。

參見

當除法或求余運算的第二個參數(shù)為零時會引發(fā) ZeroDivisionError 。

signal.SIGHUP

在控制終端上檢測到掛起或控制進程的終止。

可用性: Unix。

signal.SIGILL

非法指令。

signal.SIGINT

來自鍵盤的中斷 (CTRL + C)。

默認的動作是引發(fā) KeyboardInterrupt。

signal.SIGKILL

終止信號。

它不能被捕獲、阻塞或忽略。

可用性: Unix。

signal.SIGPIPE

損壞的管道:寫入到?jīng)]有讀取器的管道。

默認的動作是忽略此信號。

可用性: Unix。

signal.SIGSEGV

段錯誤:無效的內(nèi)存引用。

signal.SIGSTKFLT

Stack fault on coprocessor. The Linux kernel does not raise this signal: it can only be raised in user space.

Availability: Linux.

On architectures where the signal is available. See the man page signal(7)) for further information.

3.11 新版功能.

signal.SIGTERM

終結(jié)信號。

signal.SIGUSR1

用戶自定義信號 1。

可用性: Unix。

signal.SIGUSR2

用戶自定義信號 2。

可用性: Unix。

signal.SIGWINCH

窗口調(diào)整大小信號。

可用性: Unix。

SIG*

所有信號編號都是符號化定義的。 例如,掛起信號被定義為 signal.SIGHUP;變量的名稱與 C 程序中使用的名稱相同,具體見 。 ‘signal()‘ 的 Unix 手冊頁面列出了現(xiàn)有的信號 (在某些系統(tǒng)上這是 signal(2)),在其他系統(tǒng)中此列表則是在 signal(7)) 中)。 請注意并非所有系統(tǒng)都會定義相同的信號名稱集;只有系統(tǒng)所定義的名稱才會由此模塊來定義。

signal.CTRL_C_EVENT

對應(yīng)于 Ctrl+C 擊鍵事件的信號。此信號只能用于 os.kill() 。

可用性: Windows。

3.2 新版功能.

signal.CTRL_BREAK_EVENT

對應(yīng)于 Ctrl+Break 擊鍵事件的信號。此信號只能用于 os.kill() 。

可用性: Windows。

3.2 新版功能.

signal.NSIG

One more than the number of the highest signal number. Use valid_signals() to get valid signal numbers.

signal.ITIMER_REAL

實時遞減間隔計時器,并在到期時發(fā)送 SIGALRM 。

signal.ITIMER_VIRTUAL

僅在進程執(zhí)行時遞減間隔計時器,并在到期時發(fā)送 SIGVTALRM 。

signal.ITIMER_PROF

當進程執(zhí)行時以及當系統(tǒng)替進程執(zhí)行時都會減小間隔計時器。 這個計時器與 ITIMER_VIRTUAL 相配結(jié),通常被用于分析應(yīng)用程序在用戶和內(nèi)核空間中花費的時間。 SIGPROF 會在超期時被發(fā)送。

signal.SIG_BLOCK

pthread_sigmask() 的 how 形參的一個可能的值,表明信號將會被阻塞。

3.3 新版功能.

signal.SIG_UNBLOCK

pthread_sigmask() 的 how 形參的是個可能的值,表明信號將被解除阻塞。

3.3 新版功能.

signal.SIG_SETMASK

pthread_sigmask() 的 how 形參的一個可能的值,表明信號掩碼將要被替換。

3.3 新版功能.

signal 模塊定義了一個異常:

exception signal.ItimerError

作為來自下層 setitimer() 或 getitimer() 實現(xiàn)錯誤的信號被引發(fā)。 如果將無效的定時器或負的時間值傳給 setitimer() 就導致這個錯誤。 此錯誤是 OSError 的子類型。

3.3 新版功能: 此錯誤是 IOError 的子類型,現(xiàn)在則是 OSError 的別名。

signal 模塊定義了以下函數(shù):

signal.alarm(time)

如果 time 值非零,則此函數(shù)將要求將一個 SIGALRM 信號在 time 秒內(nèi)發(fā)往進程。 任何在之前排入計劃的警報都會被取消(在任何時刻都只能有一個警報被排入計劃)。 后續(xù)的返回值將是任何之前設(shè)置的警報被傳入之前的秒數(shù)。 如果 time 值為零,則不會將任何警報排入計劃,并且任何已排入計劃的警報都會被取消。 如果返回值為零,則目前沒有任何警報被排入計劃。

可用性: Unix。

signal.getsignal(signalnum)

返回當前用于信號 signalnum 的信號處理程序。 返回值可以是一個 Python 可調(diào)用對象,或是特殊值 signal.SIG_IGN, signal.SIG_DFL 或 None 之一。 在這里,signal.SIG_IGN 表示信號在之前被忽略,signal.SIG_DFL 表示之前在使用默認的信號處理方式,而 None 表示之前的信號處理程序未由 Python 安裝。

signal.strsignal(signalnum)

返回信號 signalnum 的系統(tǒng)描述,例如 “Interrupt”, “Segmentation fault” 等等。 如果信號無法被識別則返回 None。

3.8 新版功能.

signal.valid_signals()

返回本平臺上的有效信號編號集。 這可能會少于 range(1, NSIG),如果某些信號被系統(tǒng)保留作為內(nèi)部使用的話。

3.8 新版功能.

signal.pause()

使進程休眠直至接收到一個信號;然后將會調(diào)用適當?shù)奶幚沓绦颉?返回空值。

可用性: Unix。

另請參閱 sigwait(), sigwaitinfo(), sigtimedwait() 和 sigpending()。

signal.raise_signal(signum)

向調(diào)用方進程發(fā)送一個信號。 返回空值。

3.8 新版功能.

signal.pidfd_send_signal(pidfd, sig, siginfo=None, flags=0)

發(fā)送信號 sig 到文件描述符 pidfd 所指向的進程。 Python 目前不支持 siginfo 形參;它必須為 None。 提供 flags 參數(shù)是為了將來擴展;當前未定義旗標值。

更多信息請參閱 pidfd_send_signal(2)) 手冊頁面。

Availability: Linux >= 5.1

3.9 新版功能.

signal.pthread_kill(thread_id, signalnum)

將信號 signalnum 發(fā)送至與調(diào)用者在同一進程中另一線程 thread_id。 目標線程可被用于執(zhí)行任何代碼(Python或其它)。 但是,如果目標線程是在執(zhí)行 Python 解釋器,則 Python 信號處理程序?qū)?由主解釋器的主線程來執(zhí)行。 因此,將信號發(fā)送給特定 Python 線程的唯一作用在于強制讓一個正在運行的系統(tǒng)調(diào)用失敗并拋出 InterruptedError。

使用 threading.get_ident() 或 threading.Thread 對象的 ident 屬性為 thread_id 獲取合適的值。

如果 signalnum 為 0,則不會發(fā)送信號,但仍然會執(zhí)行錯誤檢測;這可被用來檢測目標線程是否仍在運行。

引發(fā)一個 審計事件 signal.pthread_kill,附帶參數(shù) thread_id, signalnum

可用性: Unix。

另請參閱 os.kill()。

3.3 新版功能.

signal.pthread_sigmask(how, mask)

獲取和/或修改調(diào)用方線程的信號掩碼。 信號掩碼是一組傳送過程目前為調(diào)用者而阻塞的信號集。 返回舊的信號掩碼作為一組信號。

該調(diào)用的行為取決于 how 的值,具體見下。

  • SIG_BLOCK: 被阻塞信號集是當前集與 mask 參數(shù)的并集。

  • SIG_UNBLOCK: mask 中的信號會從當前已阻塞信號集中被移除。 允許嘗試取消對一個非阻塞信號的阻塞。

  • SIG_SETMASK: 已阻塞信號集會被設(shè)為 mask 參數(shù)的值。

mask 是一個信號編號集合 (例如 {signal.SIGINT, signal.SIGTERM})。 請使用 valid_signals() 表示包含所有信號的完全掩碼。

例如,signal.pthread_sigmask(signal.SIG_BLOCK, []) 會讀取調(diào)用方線程的信號掩碼。

SIGKILL 和 SIGSTOP 不能被阻塞。

可用性: Unix。

另請參閱 pause(), sigpending() 和 sigwait()。

3.3 新版功能.

signal.setitimer(which, seconds, interval=0.0)

設(shè)置由 which 指明的給定間隔計時器 (signal.ITIMER_REAL, signal.ITIMER_VIRTUAL 或 signal.ITIMER_PROF 之一) 在 seconds 秒 (接受浮點數(shù)值,為與 alarm() 之差) 之后開始并在每 interval 秒間隔時 (如果 interval 不為零) 啟動。 由 which 指明的間隔計時器可通過將 seconds 設(shè)為零來清空。

當一個間隔計時器啟動時,會有信號發(fā)送至進程。 所發(fā)送的具體信號取決于所使用的計時器;signal.ITIMER_REAL 將發(fā)送 SIGALRM, signal.ITIMER_VIRTUAL 將發(fā)送 SIGVTALRM, 而 signal.ITIMER_PROF 將發(fā)送 SIGPROF.

原有的值會以元組: (delay, interval) 的形式被返回。

嘗試傳入無效的計時器將導致 ItimerError。

可用性: Unix。

signal.getitimer(which)

返回由 which 指明的給定間隔計時器當前的值。

可用性: Unix。

signal.set_wakeup_fd(fd, **, warn_on_full_buffer=True*)

將喚醒文件描述符設(shè)為 fd。 當接收到信號時,會將信號編號以單個字節(jié)的形式寫入 fd。 這可被其它庫用來喚醒一次 poll 或 select 調(diào)用,以允許該信號被完全地處理。

原有的喚醒 fd 會被返回(或者如果未啟用文件描述符喚醒則返回 -1)。 如果 fd 為 -1,文件描述符喚醒會被禁用。 如果不為 -1,則 fd 必須為非阻塞型。 需要由庫來負責在重新調(diào)用 poll 或 select 之前從 fd 移除任何字節(jié)數(shù)據(jù)。

當啟用線程用時,此函數(shù)只能從 主解釋器的主線程 被調(diào)用;嘗試從另一線程調(diào)用它將導致 ValueError 異常被引發(fā)。

使用此函數(shù)有兩種通常的方式。 在兩種方式下,當有信號到達時你都是用 fd 來喚醒,但之后它們在確定達到的一個或多個信號 which 時存在差異。

在第一種方式下,我們從 fd 的緩沖區(qū)讀取數(shù)據(jù),這些字節(jié)值會給你信號編號。 這種方式很簡單,但在少數(shù)情況下會發(fā)生問題:通常 fd 將有緩沖區(qū)空間大小限制,如果信號到達得太多且太快,緩沖區(qū)可能會爆滿,有些信號可能丟失。 如果你使用此方式,則你應(yīng)當設(shè)置 warn_on_full_buffer=True,當信號丟失時這至少能將警告消息打印到 stderr。

在第二種方式下,我們 只會 將喚醒 fd 用于喚醒,而忽略實際的字節(jié)值。 在此情況下,我們所關(guān)心的只有 fd 的緩沖區(qū)為空還是不為空;爆滿的緩沖區(qū)完全不會導致問題。 如果你使用此方式,則你應(yīng)當設(shè)置 warn_on_full_buffer=False,這樣你的用戶就不會被虛假的警告消息所迷惑。

在 3.5 版更改: 在 Windows 上,此函數(shù)現(xiàn)在也支持套接字處理。

在 3.7 版更改: 添加了 warn_on_full_buffer 形參。

signal.siginterrupt(signalnum, flag)

更改系統(tǒng)調(diào)用重啟行為:如果 flag 為 False,系統(tǒng)調(diào)用將在被信號 signalnum 中斷時重啟,否則系統(tǒng)調(diào)用將被中斷。 返回空值。

可用性: Unix。

請注意用 signal() 安裝信號處理程序?qū)⒅貑⑿袨橹刂脼榭赏ㄟ^顯式調(diào)用 siginterrupt() 并為給定信號的 flag 設(shè)置真值來實現(xiàn)中斷。

signal.signal(signalnum, handler)

將信號 signalnum 的處理程序設(shè)為函數(shù) handlerhandler 可以為接受兩個參數(shù)(見下)的 Python 可調(diào)用對象,或者為特殊值 signal.SIG_IGN 或 signal.SIG_DFL 之一。 之前的信號處理程序?qū)⒈环祷兀▍⒁娚衔?getsignal() 的描述)。 (更多信息請參閱 Unix 手冊頁面 signal(2))。)

當啟用線程用時,此函數(shù)只能從 主解釋器的主線程 被調(diào)用;嘗試從另一線程調(diào)用它將導致 ValueError 異常被引發(fā)。

handler 將附帶兩個參數(shù)調(diào)用:信號編號和當前堆棧幀 (None 或一個幀對象;有關(guān)幀對象的描述請參閱 類型層級結(jié)構(gòu)描述 或者參閱 inspect 模塊中的屬性描述)。

在 Windows 上,signal() 調(diào)用只能附帶 SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM 或 SIGBREAK。 任何其他值都將引發(fā) ValueError。 請注意不是所有系統(tǒng)都定義了同樣的信號名稱集合;如果一個信號名稱未被定義為 SIG* 模塊層級常量則將引發(fā) AttributeError。

signal.sigpending()

檢查正在等待傳送給調(diào)用方線程的信號集合(即在阻塞期間被引發(fā)的信號)。 返回正在等待的信號集合。

可用性: Unix。

另請參閱 pause(), pthread_sigmask() 和 sigwait()。

3.3 新版功能.

signal.sigwait(sigset)

掛起調(diào)用方線程的執(zhí)行直到信號集合 sigset 中指定的信號之一被傳送。 此函數(shù)會接受該信號(將其從等待信號列表中移除),并返回信號編號。

可用性: Unix。

另請參閱 pause(), pthread_sigmask(), sigpending(), sigwaitinfo() 和 sigtimedwait()。

3.3 新版功能.

signal.sigwaitinfo(sigset)

掛起調(diào)用方線程的執(zhí)行直到信號集合 sigset 中指定的信號之一被傳送。 此函數(shù)會接受該信號并將其從等待信號列表中移除。 如果 sigset 中的信號之一已經(jīng)在等待調(diào)用方線程,此函數(shù)將立即返回并附帶有關(guān)該信號的信息。 被傳送信號的信號處理程序不會被調(diào)用。 如果該函數(shù)被某個不在 sigset 中的信號中斷則會引發(fā) InterruptedError。

返回值是一個代表 siginfo_t 結(jié)構(gòu)體所包含數(shù)據(jù)的對象,具體為: si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band。

可用性: Unix。

另請參閱 pause(), sigwait() 和 sigtimedwait()。

3.3 新版功能.

在 3.5 版更改: 當被某個 不在 sigset 中的信號中斷時本函數(shù)將進行重試并且信號處理程序不會引發(fā)異常(請參閱 PEP 475 了解其理由)。

signal.sigtimedwait(sigset, timeout)

類似于 sigwaitinfo(),但會接受一個額外的 timeout 參數(shù)來指定超時限制。 如果將 timeout 指定為 0,則會執(zhí)行輪詢。 如果發(fā)生超時則返回 None。

可用性: Unix。

另請參閱 pause(), sigwait() 和 sigwaitinfo()。

3.3 新版功能.

在 3.5 版更改: 現(xiàn)在當此函數(shù)被某個不在 sigset 中的信號中斷時將以計算出的 timeout 進行重試并且信號處理程序不會引發(fā)異常(請參閱 PEP 475 了解其理由)。

Examples

這是一個最小示例程序。 它使用 alarm() 函數(shù)來限制等待打開一個文件所花費的時間;這在文件為無法開啟的串行設(shè)備時會很有用處,此情況通常會導致 os.open() 無限期地掛起。 解決辦法是在打開文件之前設(shè)置 5 秒鐘的 alarm;如果操作耗時過長,將會發(fā)送 alarm 信號,并且處理程序會引發(fā)一個異常。

 
 
 
 
  1. import signal, os
  2. def handler(signum, frame):
  3. signame = signal.Signals(signum).name
  4. print(f'Signal handler called with signal {signame} ({signum})')
  5. raise OSError("Couldn't open device!")
  6. # Set the signal handler and a 5-second alarm
  7. signal.signal(signal.SIGALRM, handler)
  8. signal.alarm(5)
  9. # This open() may hang indefinitely
  10. fd = os.open('/dev/ttyS0', os.O_RDWR)
  11. signal.alarm(0) # Disable the alarm

對于 SIGPIPE 的說明

將你的程序用管道輸出到工具例如 head(1)) 將會導致 SIGPIPE 信號在其標準輸出的接收方提前關(guān)閉時被發(fā)送到你的進程。 這將引發(fā)一個異常例如 BrokenPipeError: [Errno 32] Broken pipe。 要處理這種情況,請對你的入口點進行包裝以捕獲此異常,如下所示:

 
 
 
 
  1. import os
  2. import sys
  3. def main():
  4. try:
  5. # simulate large output (your code replaces this loop)
  6. for x in range(10000):
  7. print("y")
  8. # flush output here to force SIGPIPE to be triggered
  9. # while inside this try block.
  10. sys.stdout.flush()
  11. except BrokenPipeError:
  12. # Python flushes standard streams on exit; redirect remaining output
  13. # to devnull to avoid another BrokenPipeError at shutdown
  14. devnull = os.open(os.devnull, os.O_WRONLY)
  15. os.dup2(devnull, sys.stdout.fileno())
  16. sys.exit(1) # Python exits with error code 1 on EPIPE
  17. if __name__ == '__main__':
  18. main()

請不要將 SIGPIPE 的處置方式設(shè)為 SIG_DFL 以避免 BrokenPipeError。 這樣做還會在你的程序所寫入的任何套接字連接中斷時導致你的程序異常退出。

有關(guān)信號處理句柄和異常的注釋

如果一個信號處理句柄引發(fā)了異常,該異常將被傳播到主線程并可能在任何 bytecode 指令之后被引發(fā),在執(zhí)行期間的任何時候都可能出現(xiàn) KeyboardInterrupt。 大多數(shù) Python 代碼,包括標準庫的代碼都不能對此進行健壯性處理,因此 KeyboardInterrupt (或由信號處理句柄所導致的任何其他異常) 可能會在極少數(shù)情況下使程序處于非預期的狀態(tài)。

為了展示這個問題,請考慮以下代碼:

 
 
 
 
  1. class SpamContext:
  2. def __init__(self):
  3. self.lock = threading.Lock()
  4. def __enter__(self):
  5. # If KeyboardInterrupt occurs here, everything is fine
  6. self.lock.acquire()
  7. # If KeyboardInterrupt occurs here, __exit__ will not be called
  8. ...
  9. # KeyboardInterrupt could occur just before the function returns
  10. def __exit__(self, exc_type, exc_val, exc_tb):
  11. ...
  12. self.lock.release()

對于許多程序,特別是那些在遇到 KeyboardInterrupt 只需直接退出的程序來說,這不是個問題,但是高復雜度或要求高可靠性的應(yīng)用程序則應(yīng)當避免由于信號處理句柄引發(fā)異常。 他們還應(yīng)當避免將捕獲 KeyboardInterrupt 作為程序關(guān)閉的優(yōu)雅方式。 相反地,他們應(yīng)當安裝自己的 SIGINT 處理句柄。 下面是一個避免了 KeyboardInterrupt 的 HTTP 服務(wù)器示例:

 
 
 
 
  1. import signal
  2. import socket
  3. from selectors import DefaultSelector, EVENT_READ
  4. from http.server import HTTPServer, SimpleHTTPRequestHandler
  5. interrupt_read, interrupt_write = socket.socketpair()
  6. def handler(signum, frame):
  7. print('Signal handler called with signal', signum)
  8. interrupt_write.send(b'\0')
  9. signal.signal(signal.SIGINT, handler)
  10. def serve_forever(httpd):
  11. sel = DefaultSelector()
  12. sel.register(interrupt_read, EVENT_READ)
  13. sel.register(httpd, EVENT_READ)
  14. while True:
  15. for key, _ in sel.select():
  16. if key.fileobj == interrupt_read:
  17. interrupt_read.recv(1)
  18. return
  19. if key.fileobj == httpd:
  20. httpd.handle_request()
  21. print("Serving on port 8000")
  22. httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler)
  23. serve_forever(httpd)
  24. print("Shutdown...")

文章標題:創(chuàng)新互聯(lián)Python教程:signal—-設(shè)置異步事件處理程序
文章分享:http://m.5511xx.com/article/dpeeecc.html