[英]ValueError: signal only works in main thread (Python / Scrapy + Flask )
[英]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()。
你使用哪個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.