You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程中子进程获取用户输入的问题及可行方案咨询

Hey there, let's work through this problem together!

The core issue here is that when using the spawn start method in multiprocessing, child processes don't inherit the parent's stdin properly, and you can't pickle file objects (like your newstdin) to pass them between processes. Let's look at two solid solutions, starting with the most reliable one.


Instead of trying to make the child process read stdin directly, have the child send a request to the main process, which handles the input and sends the result back. This follows multiprocessing best practices and avoids stdin-related headaches.

Here's how to adjust your code:

main.py

import multiprocessing as mp
import sys
from child_process_01 import Child_Process_01
from child_process_02 import Child_Process_02

if __name__ == "__main__":
    mp.set_start_method("spawn")
    c1_c2_q = mp.Queue(maxsize=1)
    # Add two new queues for input requests/responses
    input_request_q = mp.Queue()
    input_response_q = mp.Queue()

    # Start child processes
    c1 = mp.Process(target=Child_Process_01, args=(c1_c2_q,))
    c1.daemon = True
    c1.start()

    c2 = mp.Process(target=Child_Process_02, args=(c1_c2_q, input_request_q, input_response_q))
    c2.daemon = True
    c2.start()

    # Main process handles all user input requests from C2
    while True:
        try:
            # Wait for a prompt from C2
            prompt = input_request_q.get()
            usr_input = input(prompt)
            input_response_q.put(usr_input)
        except KeyboardInterrupt:
            # Handle Ctrl+C to exit cleanly
            break

child_process_02.py

import multiprocessing as mp

def Child_Process_02(c1_c2_q, input_request_q, input_response_q):
    while True:
        try:
            message = c1_c2_q.get_nowait()
        except mp.Queue.Empty:
            message = None
        
        if message:
            if message == "something":  # Fix: use == instead of = for comparison
                # Send input request to main process
                input_request_q.put('In this situation, I need user input: ')
                # Wait for the response
                usr_input = input_response_q.get()
                print(f"C2 received user input: {usr_input}")

child_process_01.py (example message producer)

import time

def Child_Process_01(c1_c2_q):
    while True:
        # Simulate generating a trigger message
        c1_c2_q.put("something")
        time.sleep(3)  # Send message every 3 seconds

This approach works because:

  • The main process retains full access to stdin
  • All communication happens via pickle-safe queues
  • You avoid race conditions or platform-specific stdin issues

Solution 2: Pass the Stdin File Descriptor (Platform-Dependent)

If you really need the child process to read stdin directly, you can pass the raw file descriptor integer (instead of the TextIOWrapper object) and re-open it in the child. Note this may not work reliably on Windows, as spawn doesn't inherit file descriptors the same way as Unix-like systems.

main.py

import multiprocessing as mp
import sys
import os
from child_process_01 import Child_Process_01
from child_process_02 import Child_Process_02

if __name__ == "__main__":
    mp.set_start_method("spawn")
    c1_c2_q = mp.Queue(maxsize=1)
    # Get the raw file descriptor for stdin
    stdin_fd = sys.stdin.fileno()

    c1 = mp.Process(target=Child_Process_01, args=(c1_c2_q,))
    c1.daemon = True
    c1.start()

    c2 = mp.Process(target=Child_Process_02, args=(c1_c2_q, stdin_fd))
    c2.daemon = True
    c2.start()

    c1.join()
    c2.join()

child_process_02.py

import sys
import os
import multiprocessing as mp

def Child_Process_02(c1_c2_q, stdin_fd):
    # Re-open the file descriptor as stdin
    sys.stdin = os.fdopen(stdin_fd, 'r')
    while True:
        try:
            message = c1_c2_q.get_nowait()
        except mp.Queue.Empty:
            message = None
        
        if message:
            if message == "something":
                usr_input = input('In this situation, I need user input: ')
                print(f"C2 received user input: {usr_input}")

Final Notes

Stick with Solution 1 if you want cross-platform reliability—it's the safest way to handle user input in multiprocessing setups. Solution 2 is a workaround but may break on Windows or cause unexpected behavior if multiple processes try to read stdin at once.

内容的提问来源于stack exchange,提问作者Carlo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:24:07