为什么我的多进程没有在 main 中没有 time.sleep 的情况下启动?

Why are my multiprocesses not starting without time.sleep in main?

我有一些后台任务想要启动并能够通过用户输入安全退出。 为此,我有一个线程,其中启动了一个具有连续任务的进程池。有一个输入锁来停止打印并等待用户输入和一个事件来停止整个过程。 令我惊讶的是,如果在带有 processpool 的线程启动后有一个 time.sleep(main 中的第 6 行)。

,则这些进程似乎开始并完成它们的工作。
import multiprocessing as mp
import time
import threading as tr


def init(e, l):
    global stop_event
    global input_lock
    stop_event = e
    input_lock = l


def stupid_task(n):
    while not stop_event.is_set():
        with input_lock:
            print(n)
        time.sleep(2)


def test_mng(n, event, lock):
    with mp.Pool(n, initializer=init, initargs=(event, lock,)) as p:
        print("before")
        p.map(stupid_task, range(1, n + 1))
        print("after")
        p.close()
        p.join()


def main():
    i_lock = mp.Lock()
    s_event = mp.Event()
    thread = tr.Thread(target=test_mng, args=(3, s_event, i_lock))
    init(s_event,i_lock)
    thread.start()
    time.sleep(1) # if this line is commented out only "before" is printed
    while not stop_event.is_set():
        input("")
        with input_lock:
            print("stopped")
            eingabe = input("type q to quit")
            if eingabe == "q":
                stop_event.set()


if __name__ == "__main__":
    main()

我问自己是什么阻止了进程池的工作。我做错了什么吗? time.sleep 似乎有点老套。

我认为,您是 运行 来自 IDE(如 PyCharm)的脚本,而不是来自控制台。您的 IDE 正在捕获键盘事件。

您可以简化处理:

  • 主进程可以等待用户输入,
  • 线程可以做 "stupid task".

这是一个可能的解决方案:

# coding: utf-8
import multiprocessing as mp
import threading as tr
import time

stop_event = None


def init(event):
    global stop_event
    stop_event = event


def stupid_task(n):
    while not stop_event.is_set():
        print(n)
        time.sleep(2)


def test_mng(n, event):
    with mp.Pool(n, initializer=init, initargs=(event,)) as p:
        print("before")
        p.map(stupid_task, range(1, n + 1))
        print("after")
        p.close()
        p.join()


def main():
    print("type 'q' <ENTER> to quit")
    s_event = mp.Event()
    init(s_event)

    thread = tr.Thread(target=test_mng, args=(3, s_event,))
    thread.start()

    while not stop_event.is_set():
        c = input("")
        if c in "qQ":
            stop_event.set()


if __name__ == "__main__":
    main()