Python 2.7 发送信号(signal.SIGINT)不工作?

Python 2.7 发送信号(signal.SIGINT)不工作?,python-2.7,subprocess,sigint,keyboardinterrupt,Python 2.7,Subprocess,Sigint,Keyboardinterrupt,我创建了两个简单的脚本: script.py: import time import sys import signal try: print('i am running') time.sleep(10) print('i am done') except KeyboardInterrupt: print("you don't like me??") 和test.py: import subprocess import signal from threading

我创建了两个简单的脚本:

script.py:

import time
import sys
import signal
try:
    print('i am running')
    time.sleep(10)
    print('i am done')
except KeyboardInterrupt:
    print("you don't like me??")
和test.py:

import subprocess
import signal
from threading import Thread
import time
import os

p = subprocess.Popen('python script.py', shell=True)
t = Thread(target=p.wait)
t.start()
print('sleeping')
time.sleep(2)
print('interrupt')
p.send_signal(signal.SIGINT)
#p.send_signal(signal.SIGTERM)
t.join()
print('process finished')
如果我运行test.py(在ubuntu上),预期结果将是:

sleeping
i am running
interrupt
you don't like me??
process finished
相反,SIGINT似乎被忽略了:

sleeping
i am running
interrupt
i am done
process finished
SIGTERM按预期终止进程。但是,不会引发键盘中断

即使我将以下行添加到script.py

def signal_handler(signal, frame):
    print('You pressed Ctrl+C!')
signal.signal(signal.SIGINT, signal_handler)
似乎没有收到任何信号

但是,当我自己按下C+CTRL键时,会收到一个信号。但这不是我的选择,因为SIGINT必须是时间触发的

有人知道为什么会这样吗

干杯, Thomas

(我在示例中删除了线程的使用,因为它除了增加更多的代码行之外,不会向示例中添加任何内容)

这与流程组中如何处理信号有关,您可能会发现答案很有帮助

import subprocess
import signal
import time
import os

p = subprocess.Popen('python script.py', shell=True, preexec_fn=os.setsid) 

print('sleeping')
time.sleep(2)
os.killpg(os.getpgid(p.pid), signal.SIGINT)
print('interrupt')


p.wait()
print('process finished')
这将产生预期的结果:

andy@batman[14:58:04]:~/so$ python test.py 
sleeping
i am running
interrupt
you don't like me??
process finished
信号由进程组处理,因此从进程组中的进程发送信号并不像您想象的那样工作


有趣的是,如果不使用
shell=True
(),它就可以正常工作

import subprocess
import signal
import time
import os

p = subprocess.Popen(['python', 'script.py'])

print('sleeping')
time.sleep(2)
p.send_signal(signal.SIGINT)
print('interrupt')


p.wait()
print('process finished')

所以如果我诚实的话,这个答案有点垃圾,因为我可以告诉你两件表面上有效的事情,但不能真正解释为什么