【问题标题】:Running threading + queue in a daemon process在守护进程中运行线程+队列
【发布时间】:2014-07-27 17:00:57
【问题描述】:

我已经在 Python 文件 myfile.py 中成功实现了线程 + 队列。现在我希望这个文件作为守护进程运行,因为当所有线程都完成了它们的任务时,我想重新填充队列并让线程处理新任务。我在这里尝试了一些代码,但程序没有正确响应:

# myfile.py

threadList = list()
i = 0
while i < 10:
    i += 1
    threadName = "T" + str(i)
    threadList.append(threadName)

#create queue
myQueue = Queue.Queue();

# create thread objects
threads = list()
for threadName in threadList:
    thread = WorkerThread(threadName, myQueue)
    thread.start()
    threads.append(thread)

def hello():    
    while True:
        logger.debug("true")
        if myQueue.empty():
            logger.debug("empty")
        else:
            logger.debug("not empty")

def run():
    daemon_context = daemon.DaemonContext(files_preserve=[handler.stream],
                                          stdout = open("./stdout.log","wb"),
                                          stderr = open("./stderr.log","wb"))
    with daemon_context:
        hello()

if __name__ == "__main__":
    run()

当脚本执行时,它会打印“true”并停在那里。它不会记录“空”或“非空”。终端和 stderr.log 中没有显示错误。但是,如果我删除myQueue.empty() 的条件检查,守护程序将继续打印“true”。为什么队列在守护进程中不起作用?

【问题讨论】:

  • 您是否已通过调试器?如果是这样,请在logger.debug("true") 上休息并查看状态。采取下一步,然后看看 myQueue.empty() 正在评估什么——我已经看到标准 lib 代码会爆炸、静默失败、永远不会评估,因此永远不会进入条件评估的实例。更好的是,对于“腰带和吊带”方法,将您的 if 块包装在 try/except 中,看看是否抛出异常。这不会解决你的问题,但它会帮助你调试这里发生的事情。

标签: python multithreading python-multithreading python-daemon


【解决方案1】:

我怀疑您会看到这种奇怪的行为,因为您在守护进程之前运行了一堆代码,这在内部执行 os.fork()。这让您处于一种奇怪的状态,您的一些代码在一个进程中开始,但随后您分叉(意味着您获得了一个新进程)并开始尝试使用您在分叉之前创建的那些对象,这将无法正常工作.例如,所有正在运行的线程都会被杀死。您需要将所有您的代码移到with daemon_context 块内,才能开始工作。

不过,我会小心的。您正在使用 while True 循环快速将大量内容写入磁盘。

【讨论】:

  • 只是为了放大 OP 可能会处于什么样的奇怪状态:他们的代码很可能挂在 myQueue.empty() 上,因为当进程分叉时,工作线程正在持有队列的互斥锁;在这种情况下,主线程永远无法获得锁。
猜你喜欢
  • 2015-04-16
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
相关资源
最近更新 更多