2013-10-31 3 views
1

다음은 테스트 코드입니다.
python2.7에서 실행하면 생성 된 모든 스레드가 완료 될 때까지 프로그램에서 신호를받지 못한다는 것을 알 수 있습니다.
python3.2에서는 메인 스레드의 sigintHandler 만 호출됩니다.
파이썬이 스레드와 신호를 처리하는 방법과 혼동합니다. 그럼 스레드를 생성하고 해당 스레드 내에서 신호 처리를 수행하는 방법은 무엇입니까? 전혀 가능합니까?파이썬에서 비동기 신호 처리를 위해 별도의 스레드를 사용하는 방법

from __future__ import print_function 
from threading import Thread 
import signal, os, sys 
from time import sleep 

def sigintHandler(signo, _): 
    print("signal %d caught"%signo) 

def fn(): 
    print("thread sleeping") 
    sleep(10) 
    print("thread awakes") 

signal.signal(signal.SIGINT, sigintHandler) 

ls = [] 
for i in range(5): 
    t = Thread(target=fn) 
    ls.append(t) 
    t.start() 

print("All threads up, pid=%d"%os.getpid()) 
for i in ls: 
    i.join() 

while True: 
    sleep(20) 
+0

은'sleep (10)'을'for range (10) for for '로 바꾸면 차이가 있습니다 : sleep (1)'? – shx2

+0

그냥 시도했지만 아무런 차이가 없습니다 @ shx2 – adamsmith

답변

0

파이썬은 신호를 비동기 적으로 처리하지 않습니다. 파이썬에서 시그널 핸들러를 설치할 때, 런타임은 플래그를 설정하는 C 시그널 핸들러 스텁을 설치합니다. 인터프리터는 바이트 코드 명령어 사이의 플래그를 확인한 다음 파이썬 신호 처리기를 호출합니다. 즉, 신호 핸들러는 바이트 코드 작업 사이에서만 실행될 수 있습니다. 메인 파이썬 스레드가 C 코드를 실행 중이면 현재 작업이 완료 될 때까지 신호를 처리 할 수 ​​없습니다. 차단 된 IO를 중단하는 SIGINT (즉, control-C)에 대한 몇 가지 규정이 있지만 주 스레드에서만 가능합니다.

신호 수신을 기반으로 스레드에서 코드를 실행하려면 주 스레드에서 신호를 수신 한 다음 큐를 통해 작업자 스레드로 메시지를 보내는 것이 좋습니다. 주 스레드가 인터럽트 불가능 호출에서 차단되지 않도록해야합니다. Python 2.7에서 join은 (사용자가 발견 한 것처럼) interuptable이 아닙니다. Python의 이후 버전에서는 그렇습니다.

0

당신은 말했습니다 : python3.2에서는 메인 스레드의 sigintHandler 만 호출됩니다.

나는 그것이 옳다고 생각한다. 여기에서 : Signals and threads

파이썬 신호 처리기는 신호가 다른 스레드에서 수신되었다고해도 메인 파이썬 스레드에서 항상 실행됩니다. 즉, 신호를 스레드 간 통신 수단으로 사용할 수 없습니다. 대신 스레딩 모듈에서 동기화 기본을 사용할 수 있습니다.

게다가 메인 스레드 만 새 신호 처리기를 설정할 수 있습니다.

+0

내 의도는 스레드 간 통신을 수행하는 것이 아니라 신호를 비동기 적으로 처리하는 것입니다. – adamsmith

관련 문제