Tornado ioloop实例似乎在进程之间共享

橙子

在多处理应用程序中,一个主进程产生多个子进程。每个进程都应运行自己的Tornado ioloop。但是,我注意到,当进程启动时,IOLoop.current()(主进程和所有子进程中的)所有实例都是相同的。这不是意味着ioloop.spawn_callback(my_func)全部在一个ioloop上下文运行(在主进程中)吗?

这是我可以提取的一个最小示例:

from tornado.ioloop import IOLoop
import time
from multiprocessing import Process

def sub(i):
  print('sub %d: %s' % (i, hex(id(IOLoop.current(True)))))
  for i in range(10):
    time.sleep(1)


def main():
  print('main  ', hex(id(IOLoop.current(True))))

  for i in range(2):
    sub_process = Process(target=sub, args=(i, ))
    sub_process.daemon = True
    sub_process.start()

  time.sleep(5)

main()

输出:

main   0x7f14a09cf750
sub 0: 0x7f14a09cf750
sub 1: 0x7f14a09cf750

是否正确创建了流程,并且不是预期会有多个ioloop实例的行为?

离子t

龙卷风的文档中提到了这一点

重要的是,在派生之前,什么都不能触及全局IOLoop实例(甚至间接地)

您可以使用稍微修改的main功能来获得所需的行为

def main():
    processes = []
    for i in range(2):
        process = Process(target=sub, args=(i,))
        process.daemon = True
        process.start()
        processes.append(process)
    print('main  ', hex(id(IOLoop.current(True))))
    time.sleep(5)

输出:

main   0x7fbd4ca0da30
sub 0: 0x7fbd4ca0db50
sub 1: 0x7fbd4ca0dc40

编辑

至于解释:共享是由于fork在Linux中如何实现的:使用COW(copy-on-write); 这意味着除非您在子进程中写入共享对象,否则父级和子级都将共享同一对象。子对象修改共享对象后,将立即对其进行复制更改(这些更改在父对象中不可见)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章