赞
踩
问题的一部分来自对象变量的传递。传递args=(info,)时,传递的是reference to an object(稍后将其修改并传递给下一个对象),而不是对象的副本。将同一个对象传递给多个线程可能会很危险,因为race conditions
首先我们可以移除ContextFilter。我们正在将它们添加到全局记录器中,而不是跟踪每个线程的任何内容。在import logging
import threading
import time
logger = logging.getLogger()
syslog = logging.StreamHandler()
formatter = logging.Formatter('%(project)s : %(thread)x '
'%(levelname)-8s '
'%(message)s')
syslog.setFormatter(formatter)
logger.setLevel(logging.DEBUG)
logger.addHandler(syslog)
我发现在一般的构建中threading.Thread类对所有任务都更有用,除了最简单的任务。在
此类维护自己的running状态,并使用正确的extra数据构建自己的日志适配器。在
^{pr2}$
现在我们需要改变一些事情。我们需要使用我们自己的Worker类。在
我们不需要对记录器做任何事情,类将管理它自己的LoggerAdapter。在
我们要确保每次都创建一个新的info对象,这很简单,我们可以直接在函数调用({'project': project})中传递它,而不必指定变量。在
我们需要确保在从主线程进行日志记录时传递了project变量。用另一个LoggerAdapter可能更好。在
一旦我们中断了循环,我们可以要求每个线程停止,然后等待每个线程(join()可能会被移到Worker类的stop方法中)
^{3}$
此代码将产生如下结果project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
main : 7f4b45c8d700 DEBUG Hello from main
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
main : 7f4b45c8d700 DEBUG Hello from main
project_1 : 7f4b44180700 DEBUG Hi from project_1
有很多方法可以整理代码并使其更具可读性,但这至少应该给您一些学习和开始实验的起点。当您了解更多关于线程的信息时,您还应该阅读thread synchronization机制。我最近开始使用using ^{}s来实现线程之间的通信,这是一种更易于调试的代码。在
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。