(python) Using Threading To Look For Key Input With Getch
I've been trying to write a piece of test code which will continually print 'Running' until a key is pressed. I've tried to implement this by creating an additional thread (called
Solution 1:
You're hitting this issue because of the GIL. It works fine if you make the threading.Thread a multiprocessing.Process:
class myThread (multiprocessing.Process):
def __init__(self, threadID, name, cont):
super(myThread, self).__init__()
#threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.cont = contdef run(self):
print "Starting " + self.name +"\n"
char = getch.getch()
print 'You pressed %s' % char
cont.append(1)
print "Terminating" + self.name
cont = []
thread1 = myThread(1, "Thread1", cont)
thread1.start()
while cont == []:
print "Running"
time.sleep(0.5)
Output:
dan@dantop:~$ ./get.py
Running
Starting Thread1
Running
Running
Running
Running
Running
Running
Running
Running
You pressed f
TerminatingThread1
Running
Running
Running
Running
Running
Running
Running
Running
getch is a C-extension, and is doing a blocking call to getchar(), but it doesn't release the GIL first. Because Python cannot actually run two threads concurrently, it gets stuck in the worker thread waiting for blocking call to getchar().
You can actually fix this bug pretty easily, by explicitly releasing the GIL from the getch C-extension code, using Py_BEGIN_THREADS and Py_ALLOW_THREADS:
static PyObject *getch_getche(PyObject *self, PyObject *args)
{
int ok = PyArg_ParseTuple(args, "");
char c;
Py_BEGIN_ALLOW_THREADS
c = getche();
Py_END_ALLOW_THREADS
return PyUnicode_FromFormat("%c", c);
}
static PyObject *getch_getch(PyObject *self, PyObject *args)
{
int ok = PyArg_ParseTuple(args, "");
char c;
Py_BEGIN_ALLOW_THREADS
c = getch();
Py_END_ALLOW_THREADS
return PyUnicode_FromFormat("%c", c);
}
If you make that change to getchmodule.c and rebuild the extension, the original, thread-using, example code works fine.
Post a Comment for "(python) Using Threading To Look For Key Input With Getch"