【问题标题】:Daemon process never starting守护进程永远不会启动
【发布时间】:2015-10-29 11:03:41
【问题描述】:

我无法理解为什么守护进程从不产生“启动/退出”输出。在我调用 n.start() 的那一刻,似乎进程被杀死了

import multiprocessing
import time
import sys

def daemon():
    p = multiprocessing.current_process()
    print 'Starting:', p.name, p.pid
    sys.stdout.flush()
    print 'Exiting :', p.name, p.pid
    sys.stdout.flush()

def non_daemon():
    p = multiprocessing.current_process()
    print 'Starting:', p.name, p.pid
    sys.stdout.flush()
    time.sleep(3)
    print 'Exiting :', p.name, p.pid
    sys.stdout.flush()

if __name__ == '__main__':
    d = multiprocessing.Process(name='daemon', target=daemon)
    d.daemon = True

    n = multiprocessing.Process(name='non-daemon', target=non_daemon)
    n.daemon = False

    d.start()
    n.start()

【问题讨论】:

  • 更新:如果我在 d.start() 和 n.start() 之间添加 time.sleep(1) 代码似乎工作得很好。

标签: python python-multiprocessing


【解决方案1】:

守护进程通常与 stdin/stdout/stderr 描述符断开连接,因为它们不需要与用户进行任何交互。所以,我认为如果你想记录一些东西,你需要为 sys.stdout 分配一些自定义流(可能是一些写入文件的记录器)

更新: 您可以使用连接到父进程的pipe 测试您的代码。使用此管道,您可以将消息传输到父进程,而不是 STDOUT。

【讨论】:

  • 这里不相关。它在线程上下文中使用daemon(意味着整个进程可以退出,当所有非守护进程退出时终止守护进程),而不是 UNIX 守护进程的含义(独立进程在生成它的进程结束后仍然存在)。是的,这是一个愚蠢的超载术语。
  • 但是,multiprocessing.Process 是关于创建一个新进程,而不是一个线程,不是吗?
  • 是的,但它使用线程语义; multiprocessing 更多的是通过模拟进程的线程来解决 GIL。根据docs on the daemon flag:“这些不是 Unix 守护进程或服务,它们是正常进程,如果非守护进程退出,它们将被终止(而不是加入)。”
  • 好的,但它没有说明标准描述符。您是否声称它们连接到同一个终端,连接到哪个父进程?
  • 记住,它基本上是用进程模拟线程。描述符在fork 中正常继承(尽管您在单个进程中失去了正常标准句柄的半同步行为)。如果daemon 被终止,缓冲区可能不会被刷新,但是如果flush 在终止之前发生,则显式的flush 调用地址。
猜你喜欢
  • 1970-01-01
  • 2013-01-09
  • 2011-08-28
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
相关资源
最近更新 更多