Python time.sleep(1)引发类型错误?

2024-09-29 19:23:46 发布

您现在位置:Python中文网/ 问答频道 /正文

每当我从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

下面我展示了我的脚本在运行时的输出行为完全正常

  1. 从终点站
  2. 从带有&
  3. 来自bash脚本(不带&;)

三个人的表现都和预期的一样。。。 (以下输出与预期一致)

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.12Debian 9.12

我希望有人能弄明白

编辑:这里是错误版本的字节码的比较(使用&;从shell脚本运行)output 这是好的版本(从终端运行)output

为了便于比较,here是字节码的diff。唯一的区别是子线程在内存中的位置


Tags: pytest脚本childsh线程threadpython3

热门问题