【发布时间】:2013-06-04 23:07:32
【问题描述】:
在一个多线程 Python 进程中,我有许多 非守护进程 线程,我的意思是即使在主线程退出/停止后仍保持主进程处于活动状态的线程。 p>
我的非守护线程将weak references 保存到主线程中的某些对象,但是当主线程结束时(控制从文件底部脱落)这些对象确实不似乎是垃圾收集,我的弱引用终结器回调不会触发。
我期望主线程被垃圾收集是错误的吗?我本来期望线程本地将被释放(即垃圾收集)......
我错过了什么?
辅助材料
pprint.pprint( threading.enumerate() ) 的输出显示主线程已停止,而其他人仍在继续。
[<_MainThread(MainThread, stopped 139664516818688)>,
<LDQServer(testLogIOWorkerThread, started 139664479889152)>,
<_Timer(Thread-18, started 139663928870656)>,
<LDQServer(debugLogIOWorkerThread, started 139664437925632)>,
<_Timer(Thread-17, started 139664463103744)>,
<_Timer(Thread-19, started 139663937263360)>,
<LDQServer(testLogIOWorkerThread, started 139664471496448)>,
<LDQServer(debugLogIOWorkerThread, started 139664446318336)>]
而且由于总是有人询问用例...
我的网络服务偶尔会错过其实时截止日期(在最坏的情况下会导致整个系统故障)。事实证明,这是因为只要文件系统发脾气,记录(重要)调试数据就会阻塞。因此,我正在尝试改造一些已建立的专用日志库,以将阻塞 I/O 推迟到工作线程。
遗憾的是,已建立的使用模式是记录重叠并行事务的短期日志通道和从未显式关闭的长期模块范围通道的混合。
所以我创建了一个装饰器,它将方法调用推迟到工作线程。工作线程是非守护进程,以确保所有(慢)阻塞 I/O 在解释器退出之前完成,并持有对客户端(方法调用入队)的弱引用。当客户端被垃圾回收时,弱引用的回调触发并且工作线程知道没有更多的工作将被排队,因此将在下次方便时退出。
除了一个重要的用例之外,这似乎在所有情况下都可以正常工作:当日志记录通道位于主线程中时。当主线程停止/退出时,日志通道未最终确定,因此我的(非守护程序)工作线程继续保持整个进程处于活动状态。
【问题讨论】:
-
有很多假设必须在没有具体代码示例的情况下回答这个问题...也就是说,您是否尝试过在主线程末尾显式关闭/删除日志记录通道,只是为了看看弱引用的回调是否被触发了?
标签: python python-2.6 python-multithreading