每当我从Python3中的子线程中断/杀死休眠的父线程时,就会出现这种奇怪的行为(抛出随机TypeError异常),但只有当python脚本由带有&
参数的shell脚本启动以使其在后台运行时,才会出现这种奇怪的行为
下面是我能想到的能够触发这个问题的最小可复制python代码
User@MSI: ~/test $ cat m.py
import threading
import _thread
import time
def child_thread():
time.sleep(1)
print('child interrupting parent')
_thread.interrupt_main()
if __name__ == '__main__':
t = threading.Thread(target=child_thread, args=())
t.start()
print('parent looping')
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print('caught interruption raised from user or child thread :)')
except TypeError as e:
print('why would I ever catch a TypeError?')
raise
except Exception as e:
print('Strange Exception Received ')
raise
这是一个非常简单的脚本,父线程启动子线程,然后永远循环,子线程(1秒后)中断主线程,而主线程应该向主线程发出键盘中断
现在,如果我使用一个bash脚本调用我的脚本,该脚本的末尾带有背景标志&
,
(以下输出毫无意义)
User@MSI: ~/test $ cat ./m.sh
#!/bin/bash
python3 m.py &
User@MSI: ~/test $ ./m.sh
parent looping
child interrupting parent
why would I ever catch a TypeError?
Traceback (most recent call last):
File "m.py", line 17, in <module>
time.sleep(1)
TypeError: 'int' object is not callable
下面我展示了我的脚本在运行时的输出行为完全正常
三个人的表现都和预期的一样。。。 (以下输出与预期一致)
User@MSI: ~/test $ python3 m.py
parent looping
child interrupting parent
caught interruption raised from user or child thread :)
使用&;在后台运行时,结果相同; (以下输出与预期一致)
User@MSI: ~/test $ python3 m.py &
[1] 5884
parent looping
child interrupting parent
caught interruption raised from user or child thread :)
[1]+ Done python3 m.py
甚至从一个名为m.sh的单行脚本执行m.py (以下输出与预期一致)
User@MSI: ~/test $ cat m.sh
#!/bin/bash
python3 m.py
User@MSI: ~/test $ ./m.sh
parent looping
child interrupting parent
caught interruption raised from user or child thread :)
我完全目瞪口呆,不知道什么时候。sleep和TypeErrors与我如何调用我的脚本,特别是从shell脚本和后台调用脚本有关。这是我遇到的最奇怪的错误之一
如果重要的话,我正在运行Python 3.6.12
和Debian 9.12
我希望有人能弄明白
编辑:这里是错误版本的字节码的比较(使用&;从shell脚本运行)output 这是好的版本(从终端运行)output
为了便于比较,here是字节码的diff
。唯一的区别是子线程在内存中的位置
目前没有回答
相关问题 更多 >
编程相关推荐