以下代码会创建3个或4个日志文件。如何编写以便在保留文件名格式的同时只创建一个文件?此外,这似乎是Windows唯一的问题。当我在RHEL 5.3盒子上运行它甚至将nproc设置为1000时,我只获得1个日志文件。 [Python 3.4.1]
import datetime, logging, multiprocessing, os.path, time
logging.basicConfig(level=logging.DEBUG, format="%(asctime)-4s %(process)6s %(message)s", datefmt="%m-%d %H:%M:%S",
filename="test_%s.log"%(datetime.datetime.today().strftime("%Y%m%d-%H%M%S")))
def worker(n):
logging.info("before")
time.sleep(n)
logging.info("after")
if __name__=='__main__':
nproc = 40
pool = multiprocessing.Pool(processes=nproc)
pool.map(worker, (6,)*nproc)
答案 0 :(得分:1)
原始答案:将logging.basicConfig
电话放入您的主要声明中。
新答案:将日志记录调用添加到worker函数的开头。您可以将其放入名为setup_logging
的函数中以供将来更改。我之前的回答可能不会起作用,因为工人们没有设置日志记录。
当multiprocessing
运行新目标时,它必须启动一个全新的解释器,然后加载具有要运行的函数的模块。在您进行日志记录调用的地方,每次加载模块时都会运行它。我猜测它只在linux上创建一个文件就是运气。
我应该注意记录的正常模式(至少我使用的)是:
import logging
log = logging.getLogger(__name__)
# Code
def a_func():
log.debug("This is my message")
if __name__ == "__main__":
logging.basicConfig(...)
a_func()
编辑:如果它不清楚我的意思是运气,我的意思是你要创建一个包含当前日期/时间的文件名,这样就可以开始同时启动多个进程时间就是运气。如果操作系统需要很长时间才能启动X个工作人员,那么您将获得不同的文件名。在Linux上,它可以做一些聪明的事情,同时加载所有的解释器/模块,然后调用该函数。
您的代码:我很抱歉在累了时编写stackoverflow答案。我之前的解决方案并没有真正解决问题。这样做:
import datetime, logging, multiprocessing, os.path, time
def worker(args):
# it's not simple to pass more than one argument so we expand the tuple here
n, log_filename = args
logging.basicConfig(level=logging.DEBUG,
format="%(asctime)-4s %(process)6s %(message)s",
datefmt="%m-%d %H:%M:%S",
filename=log_filename)
logging.info("before")
time.sleep(n)
logging.info("after")
if __name__=='__main__':
filename="test_%s.log" % (datetime.datetime.today().strftime("%Y%m%d-%H%M%S"),)
nproc = 40
pool = multiprocessing.Pool(processes=nproc)
pool.map(worker, ((6, filename),)*nproc)
答案 1 :(得分:0)
您需要做几件事:
logging
模块在内部使用threading.RLock
来同步写入,但这不是进程安全的:每个进程都有自己的Rlock
,对其他进程一无所知。因此,您需要创建自己的logging.Handler
使用进程安全锁,然后与池中的每个进程共享该锁。我们可以利用initializer
的{{1}} / initargs
关键字参数来实现这一目标。我们只需将在所有工作进程中创建相同记录器所需的所有参数传递给multiprocessing.Pool
函数,然后为每个进程构建一个全局initializer
对象。
这是一个有效的例子:
logging.Logger