redmaw
redmaw

Reputation: 325

input() blocks other python processes in Windows 8 (python 3.3)

Working on a multi-threaded cross-platform python3.3 application I came across some weird behavior I was not expecting and am not sure is expected. The issue is on Windows 8 calling the input() method in one thread blocks other threads until it completes. I have tested the below example script on three Linux, two Windows 7 and one Windows 8 computers and this behavior is only observed on the Windows 8 computer. Is this expected behavior for Windows 8?

test.py:

import subprocess, threading, time

def ui():
    i = input("-->")
    print(i)

def loop():
    i = 0
    f = 'sky.{}'.format(i)
    p = subprocess.Popen(['python', 'copy.py', 'sky1', f])
    t = time.time()
    while time.time() < t+15:
        if p.poll() != None:
            print(i)
            time.sleep(3)
            i+=1
            f = 'sky.{}'.format(i)
            p = subprocess.Popen(['python', 'copy.py', 'sky1', f])
    p.terminate()
    p.wait()

def start():
    t1 = threading.Thread(target=ui)
    t2 = threading.Thread(target=loop)
    t1.start()
    t2.start()
    return t2

t2 = start()
t2.join()
print('done')

copy.py:

import shutil
import sys

src = sys.argv[1]
dst = sys.argv[2]

print('Copying \'{0}\' to \'{1}\''.format(src, dst))
shutil.copy(src, dst)

Update: While trying out one of the suggestions I realized that I rushed to a conclusion missing something obvious. I apologize for getting off to a false start.

As Schollii suggested just using threads (no subprocess or python files) results in all threads making forward progress so the problem actually is using input() in one python process will cause other python processes to block/not run (I do not know exactly what is going on). Furthermore, it appears to be just python processes that are affected. If I use the same code shown above (with some modifications) to execute non-python executables with subprocess.Popen they will run as expected.

To summarize:

Side Note: I do not have Windows 8 platform so debugging/tests can be a little slow.

Upvotes: 18

Views: 2027

Answers (2)

Siva Cn
Siva Cn

Reputation: 947

It's a very good problem to work with,

since you are dependent with input() method, which, usually needs the console input,

since you have threads, all the threads are trying to communicate with the console,

So, I advice you to use either Producer-Consumer concept or define all your inputs to a text file and pass the text file to the program.

Upvotes: 1

Colin O&#39;Coal
Colin O&#39;Coal

Reputation: 1427

Because there are several problems with input in Python 3.0-3.2 this method has been impacted with few changes.

It's possible that we have a new bug again.

Can you try the following variant, which is raw_input() "back port" (which was avaiable in Python 2.x):

...
i = eval(input("-->"))
...

Upvotes: 1

Related Questions