【问题标题】:queue consumer print vs logging [duplicate]队列消费者打印与日志记录[重复]
【发布时间】:2018-02-20 15:30:30
【问题描述】:

在调试下面的队列示例时,我发现了一个与 Python 3.6 中的打印函数相关的奇怪行为(对我来说)。下面的代码按预期工作,但是,如果我在下面的消费者函数中用“print”函数更改“logger.info”,消费者函数就会挂起。为什么会这样?

from queue import Queue
from threading import Thread
import logging

logging.basicConfig(format='%(asctime)s; %(name)s; %(levelname)s; %(message)s', level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.info('Starting...')


def consumer(q):
    while True:
        item = q.get()
        logger.info ("Working on item: {}".format(item))


def main():
    q = Queue()

    t = Thread(target=consumer, args=(q,))
    t.start()

    for i in range(3):
        q.put(i)

if __name__ == '__main__':
    main()

输出 1:

2018-02-20 09:24:29,630; __main__; INFO; Starting...
2018-02-20 09:24:29,631; __main__; INFO; Working on item: 0
2018-02-20 09:24:29,631; __main__; INFO; Working on item: 1
2018-02-20 09:24:29,631; __main__; INFO; Working on item: 2

输出 2:

2018-02-20 09:26:14,497; __main__; INFO; Starting...

【问题讨论】:

  • 可能是它的输出缓冲。在 Python 3.x 中,print 函数有额外的参数 flush。默认为False。也许将其设置为True 将刷新输出缓冲区。

标签: python multithreading logging queue


【解决方案1】:

这可能是因为stdout 缓冲。

在 Python 3.x 中,您有额外的参数 flush 用于打印功能。默认为False。也许将其设置为True 将刷新输出缓冲区。

不过,我想指出的是:

logger.info ("Working on item: {}".format(item))

您不应该使用format 字符串并以这种方式形成日志消息。

正确的做法是:

logger.info("Working on item: %s", item)

或许

logger.info("Working on item: {item}", item=item)

原因:最好将日志消息的创建延迟到真正需要时再创建,如果需要的话。

您可以在here找到更多相关信息。

【讨论】:

    猜你喜欢
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多