Search code examples
pythonraw-input

raw input and multiprocessing in python


I have (in the main) the following code:

status = raw_input("Host? (Y/N) ") 
if status=="Y":
    print("host")
    serverprozess = Process(target= spawn_server)
    serverprozess.start()
clientprozess = Process (target = spawn_client)
clientprozess.start()

The methods called above basically do as follows:

def spawn_server():
     mserver = server.Gameserver()
    #a process for the host. spawned if and only if the player acts as host

def spawn_client():
    myClient = client.Client()
    #and a process for the client. this is spawned regardless of the player's status

It works fine, the server spawns and so does the client.

Only yesterday I added in client.Client() the following line:

self.ip = raw_input("IP-Adress: ") 

The second raw_input throws an EOF -exception:

     ret = original_raw_input(prompt)
     EOFError: EOF when reading a line

Is there a way to fix this? Can I not use more than one prompt?


Solution

  • As you've already determined, it is easiest to call raw_input from the main process only:

    status = raw_input("Host? (Y/N) ") 
    if status=="Y":
        print("host")
        serverprozess = Process(target= spawn_server)
        serverprozess.start()
    
    ip = raw_input("IP-Address: ")     
    clientprozess = Process (target = spawn_client, args = (ip, ))
    clientprozess.start()
    

    However, using J.F. Sebastian's solution it is also possible to duplicate sys.stdin and pass it as an argument to the subprocess:

    import os
    import multiprocessing as mp
    import sys
    
    def foo(stdin):
        print 'Foo: ',
        status = stdin.readline()
        # You could use raw_input instead of stdin.readline, but 
        # using raw_input will cause an error if you call it in more 
        # than one subprocess, while `stdin.readline` does not 
        # cause an error.
        print('Received: {}'.format(status))
    
    status = raw_input('Host? (Y/N) ')
    print(status)
    newstdin = os.fdopen(os.dup(sys.stdin.fileno()))
    try:
        proc1 = mp.Process(target = foo, args = (newstdin, ))
        proc1.start()
        proc1.join()
    finally:
        newstdin.close()