簡體   English   中英

siginterrupt()僅適用於第一個信號? (蟒蛇)

[英]siginterrupt() only works for the first signal? (Python)

出於某種原因,siginterrupt()似乎只設置接收到的第一個信號的行為。

在這個示例程序中,第一個SIGQUIT似乎什么都不做,但是第二個sigquit打印“SIGQUIT Handler”和s.accept()會拋出一個Interrupted系統調用異常。

from signal import *
from socket import *
import sys

def sigquitHandler(signum, frame):
        print("SIGQUIT Handler")

s = socket()
s.bind(("0.0.0.0", int(sys.argv[1])))
s.listen(5)

signal(SIGQUIT, sigquitHandler)
siginterrupt(SIGQUIT, False)

client, addr = s.accept() # Or any syscall that blocks
client.close()
s.close()

我在這里誤會了什么?


編輯:這是我無法弄清楚的其他東西,在這個程序中,SIGQUIT中斷了select()。 這應該發生嗎?

from signal import *
import select
import sys

def sigquitHandler(signum, frame):
    print("SIGQUIT Handler")

signal(SIGQUIT, sigquitHandler)
siginterrupt(SIGQUIT, False)

select.select([sys.stdin], [], [])

這是python的一個bug “siginterrupt with flag = False在收到信號時被重置”,這已在后來的python2.6版本中得到修復。 (2.6.6 +,2.7 +)

對於第二個,siginterrupt不會影響select()。

http://lkml.org/lkml/2005/7/23/119

你使用哪個unix C級,BSD與System 5(SYSV)上的信號處理有不同的實現和語義。

我的猜測是你正在使用SYSV,在這種情況下,信號處理器返回后信號處理被重置為SIG_DFL(經典信號處理)。 在SYSV上,您需要在處理程序中調用signal以重新安裝該處理程序。

Python或多或少提供了BSD風格的信號處理。 因此,在SYSV OS上,Python必須通過signal管理信號處理程序的重新安裝。 現在,根據用於siginterrupt的Python doco:

請注意,使用signal()安裝信號處理程序會通過使用給定信號的true標志值隱式調用siginterrupt()來將重啟行為重置為可中斷。

你去吧 - 如果 Python自動重新安裝你的信號處理程序(提供像語義一樣的BSD),它可能會以隱式調用siginterrupt(1)的方式這樣做。

當然,我的猜測可能是錯的。

可以通過定義sigquitHandler來解決這個問題:

def sigquitHandler(signum, frame):
    print("SIGQUIT Handler")
    siginterrupt(SIGQUIT, False)

這取決於Python何時以及如何恢復信號處置。

編輯

siginterrupt(SIGQUIT, False)添加到信號處理程序沒有任何影響。

編輯2

在Python2.6源代碼中進行了一些討論后,它清楚地表明這不僅僅是一個SYSV問題。 它也會影響BSD系統。

暫無
暫無

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

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