Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to use input when multiprocessing in Python

I want to run 2 processes at the same time. 1 will keep printing 'a' every second and the other will ask for an input and when the input is 'Y', the first process will stop printing 'a'. I am fairly new to Python and I can't figure it out...

This is what I came up with so far:

from multiprocessing import Process
import time

go = True

def loop_a():
    global go

    while go == True:
        time.sleep(1)
        print("a")

def loop_b():
    global go
    text = input('Y/N?')

    if text == 'Y':
        go = False

if __name__ == '__main__':
    Process(target=loop_a).start()
    Process(target=loop_b).start()

This is the error message I'm getting:

Process Process-2:
Traceback (most recent call last):
  File "C:\Users\Tip\AppData\Local\Programs\Python\Python36\lib\multiprocessing\process.py", line 249, in _bootstrap
    self.run()
  File "C:\Users\Tip\AppData\Local\Programs\Python\Python36\lib\multiprocessing\process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "F:\ProgrammingTK\PROGproject\test.py", line 15, in loop_b
    text = input('Y/N?')
EOFError: EOF when reading a line
like image 707
Tipsi Avatar asked Dec 02 '25 20:12

Tipsi


1 Answers

Expanding upon jasonharper's comment as he is correct.

There are a couple issues

  1. The go variable is not shared among the processes. As Jason suggested you can use something like Manager in multiprocessing in order to share a value among multiple processes. Technically, that go variable will be copied over into each process but it won't be shared between them so a change in one process won't be seen by the other.
  2. Again, as he mentioned you need to pull the input(..) into the main thread of the program. Also, if you are on 2.7 you will need to use raw_input(..).
  3. Also, if you are only checking the flag once and then exiting then you'll likely hit a BrokenPipeError.

Taking that in, you can try something like this:

from multiprocessing import Process, Manager
import time


def loop_a(go):
    while True:
        # run forever and print out the msg if the flag is set
        time.sleep(1)
        if go.value:
            print("a")

if __name__ == '__main__':
    # shared value flag
    manager = Manager()
    go_flag = manager.Value('flag', True)

    # other process that is printing
    Process(target=loop_a, args=(go_flag,)).start()

    # normal main thread; toggle on and off the other process
    while True:
        text = input('Stop Y/N?')
        if text == 'Y':
            go_flag.value = False
            print("Changed the flag {}".format(go_flag.value))
        else:
            go_flag.value = True
            print("Changed the flag {}".format(go_flag.value))
like image 146
Paul Avatar answered Dec 05 '25 12:12

Paul



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!