gpt4 book ai didi

python - (Python) 使用线程通过 getch 查找键输入

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:23 24 4
gpt4 key购买 nike

我一直在尝试编写一段测试代码,它会不断打印“Running”,直到按下一个键。我试图通过创建一个额外的线程(称为 thread1)来实现这一点,该线程将监听按键。

当我运行我的代码时,线程启动正常,并且似乎在调用 getch.getch() 之前正确执行。当 getch.getch() 等待按键时,它似乎不仅停止了 thread1,而且还停止了主线程。

如何确保在线程 1 监听按键时,主线程继续运行?

我正在使用 python 2.7 和 getch 1.0 ( https://pypi.python.org/pypi/getch )。

这是我的代码:

import threading
import time
import getch

class myThread (threading.Thread):
def __init__(self, threadID, name, cont):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.cont = cont

def run(self):
print "Starting " + self.name +"\n"
print "waiting 2 seconds"
time.sleep(2)
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)

它输出这个:

Starting Thread1
Running

waiting 2 seconds
Running
Running
Running

它一直呆在那里直到我按下一个键

最佳答案

您遇到这个问题是因为 GIL。如果您将 threading.Thread 设为 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)

输出:

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 是一个 C 扩展,正在对 getchar() 进行阻塞调用,但它不会首先释放 GIL。因为 Python 实际上不能同时运行两个线程,它会卡在工作线程中等待阻塞调用 getchar()

实际上,您可以通过使用 Py_BEGIN_THREADSPy_ALLOW_THREADSgetch C 扩展代码中显式释放 GIL 来非常轻松地修复此错误:

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);
}

如果您对 getchmodule.c 进行更改并重建扩展,则使用线程的原始示例代码可以正常工作。

关于python - (Python) 使用线程通过 getch 查找键输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24192171/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com