pythonmultiprocessinguser-inputeoferror

How to use multiprocessing with input() function and avoid "EOFError: EOF when reading a line"?


I am presently making a Python program that is supposed to use multiprocessing where one function handles UI, and another handles updating data files. The cause of the error EOFError: EOF when reading a line is being indicated at the moment my UI function is calling for user input with the function input().

Below is simplified code that can act as an example and creates the exact same error in my real program:

import multiprocessing
import time

# Class with methods used to print strings.
class Printing:

    # Setting of initial values is ignored.
    def __init__(self):
        pass

    # Continuously calls for user input that is then printed.
    def printInput(self):
        while True:
            string = input("Enter a string: ")
            print(string)

# Continuously prints the  character "X"
def printXs():
    while True:
        time.sleep(1) # Just used to slows the printing output.
        print("X")

# Execution of script when told to run.
if __name__=='__main__':
    mp1 = multiprocessing.Process(target=printXs)
    mp2 = multiprocessing.Process(target=Printing().printInput)

    mp1.start()
    mp2.start()

The resulting error is EOFError: EOF when reading a line at line 14, or in other words the piece of code that is input ("Enter a string: ").


Solution

  • The standard input stream (stdin) is not attached to Process processes when they're created. Since it doesn't make sense to read input from the same stream by multiple processes, the default is to assume that stdin will be read exclusively by the main process.

    In your case, you are only going to take input from one process, but you want it to be one of the Process processes you've spawned. You can attach stdin in that case like this:

    def printInput(self):
        sys.stdin = open(0) # <--- Here's the magic line...you'll need to "import sys" above too
        while True:
            string = input("Enter a string: ")
            print(string)
    

    It's strange to be outputting to the console from one thread/process, while you're taking console input in another. In fact, it seems to screw things up. You don't get all the input you've typed, but rather only what's come in since the last 'X' printed. I assume that's just for playin' around purposes.