Что произойдет, если я разветвлю процесс, в котором есть поток демона? - PullRequest
0 голосов
/ 08 июня 2018

У меня вопрос: у меня есть родительский процесс A, и я настроил поток демона как RPC-сервер, такой как TaskRPCServer (Thread).Затем я хотел бы порождать дочерний процесс с использованием объекта Python multiprocessing.Process.Например: B = Process (), B.start ().У Dese B будет тот же поток демонов, что и у A?Можно ли заставить B не запускать поток демонов в A?Потому что в некоторых случаях многие процессы будут слушать порты RPC.Или, если мой дизайн был неправильным, как я могу сделать это правильно?Спасибо!

1 Ответ

0 голосов
/ 08 июня 2018

Когда вы разворачиваете дочерний процесс, он начинается только с одного потока.Это определяется POSIX : 1

Процесс должен быть создан с одним потоком.Если многопоточный процесс вызывает fork (), новый процесс должен содержать реплику вызывающего потока и всего его адресного пространства, возможно, включая состояния мьютексов и других ресурсов.

Итак, у вашего дочернего процесса не будет потока демона.Вам не нужно ничего делать, чтобы заставить это не делать.


Вы можете проверить это сами довольно легко:

import threading
import os
import time

def threadfunc():
    while True:
        print(os.getpid())
        time.sleep(1)

def main():
    t = threading.Thread(target=threadfunc)
    t.start()
    pid = os.fork()
    if pid:
        print(f'Forked {pid}; sleep time')
        time.sleep(5)
    else:
        print(f'Forked child; sleep time')
        time.sleep(5)

main()

Если вы запустите это, вы увидите что-токак это:

12345
Forked 12346; sleep time
Forked child; sleep time
12345
12345
12345

Обратите внимание, что поток демона печатал 12345, PID родительского процесса, 5 раз, и никто никогда не печатал 12346, PID дочернего процесса.


Но между тем, хотя проблемы, о которой вы спрашиваете, не существует, иногда имеют проблемы со смешиванием fork и потоков, а multiprocessing дает вам решение этих проблем, так какописанный в Контексты и методы запуска .

multiprocessing.set_start_method('forkserver') гарантирует, что ваши дочерние процессы будут запущены из чистого состояния, вплоть до потоков, мьютексов и т. д. 2 Он также защищает вас от случайного совместного использования файловых дескрипторов.(Третий вариант, spawn, обычно необходим только в том случае, если вы хотите, чтобы ваш код работал одинаково в Unix и Windows.)


1.Это может быть не так для некоторых очень старых платформ Unix, но это будет верно для любых macOS, Linux, * BSD и т. Д., Которые поддерживают потоки POSIX, по крайней мере, до 2004 , и, вероятно, раньше, но янигде не могу найти более старые и легальные спецификации POSIX / SUS онлайн ...

2.Помимо проблем, о которых предупреждают документы POSIX, существуют и более мрачные проблемы с такими вещами, как попытка запуска основного цикла Какао при многопроцессорной обработке из фонового потока.

...