当执行python脚本时,脚本在线程上阻塞,但不是在交互模式下?

时间:2018-07-08 18:38:22

标签: python multithreading

希望您能帮助我。它将需要一些解释...

TLDR问题:为什么线程进程会从myprocess.start()之类的交互模式按预期方式运行(分离的python线程)却从{{1}这样的shell运行时会阻塞子线程}?


背景:我为类python myprocess.py继承了子类,该类也调用了另外两个threading.Thread类型的子类。看起来像:

Thread

这两个服务(class Node(threading.Thread): def __init__(self, gps_device): threading.Thread.__init__(self) self.daemon = False logging.info("Setting up GPS service") self.gps_svc = gps.CoordinateService(gps_device) self.gps_svc.daemon = True logging.info("Setting up BLE scanning service") # TODO: This is blocking when run in terminal (aka how we do on Raspberry Pi) self.scan_svc = scan.BleMonitor() self.scan_svc.daemon = True logging.info("Node initialized - ready for start") def run(self): self.gps_svc.start() self.scan_svc.start() # blocks here in terminal do stuff... gps_svc)都按照解释器的意图以交互方式(如scan_svc)正常工作。当我使用脚本调用解释器时,node = Node(...); node.start()启动并起作用,但是gps_svc在侦听蓝牙设备的特定行处阻塞。

BLE扫描器在下面(它很长)。这是scan_svc的父类-没什么不同,我只添加了几个实用程序函数。


问题:为什么会这样?我可以与PROCESS而不是BleMonitor运行/交互(即:类的调用方法并实时获取数据)吗?

Thread

1 个答案:

答案 0 :(得分:1)

Python Documentation中,我认为交互式模式下的解释器在涉及线程时违反了以下条件:

在CPython中,全局解释器锁(即GIL)是一个互斥体,用于保护对Python对象的访问,从而防止多个线程一次执行Python字节码。锁定是必要的,主要是因为CPython的内存管理不是线程安全的。 (但是,由于存在GIL,因此其他功能也逐渐依赖于它所执行的保证。)

因此,存在这样的规则:只有获得GIL的线程才可以在Python对象上操作或调用Python / C API函数。为了模拟执行的并发性,解释器会定期尝试执行以下操作:切换线程(请参阅sys.setswitchinterval())。该锁定也释放在可能阻止诸如读取或写入文件之类的I / O操作的周围,以便其他Python线程可以同时运行。

我需要进一步研究,但是我的怀疑使我想到了GIL与线程对象管理之间的冲突。希望对您有所帮助或有人可以添加更多内容。