Экземпляр Tornado iol oop, похоже, используется всеми процессами - PullRequest
1 голос
/ 20 апреля 2020

В многопроцессорном приложении основной процесс порождает несколько подпроцессов. Каждый процесс предназначен для запуска собственного Tornado iol oop. Однако я заметил, что при запуске процесса все экземпляры IOLoop.current() (в основном и всех подпроцессах) совпадают. Не означает ли это, что ioloop.spawn_callback(my_func) работает все в одном контексте iol oop (в основном процессе)?

Вот минимальный пример, который я мог бы извлечь:

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

Правильно ли созданы процессы, а не ожидаемое поведение, которое могло бы быть несколькими iol oop экземпляров?

1 Ответ

1 голос
/ 21 апреля 2020

Это упоминается в документах Торнадо

. Важно, чтобы ничто не касалось глобального экземпляра IOL oop (даже косвенно) перед вилкой

Вы можете получить желаемое поведение, используя слегка модифицированную 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 (копирование при записи); это означает, что если вы не напишите в общий объект в дочернем процессе, родительский и дочерний объекты будут совместно использовать один и тот же объект. Как только дочерний объект изменяет общий объект, он будет скопирован и изменен (эти изменения не будут видны в родительском объекте).

...