【发布时间】:2023-03-29 05:31:01
【问题描述】:
我正在编写一个 Python 模块来读取 jstest 输出并使 Xbox 游戏手柄在 Linux 上的 Python 中工作。我需要在另一个看起来像这样的线程上的 __init__ 中的后台无限循环开始:
import os
from threading import Thread
import time
import select
import subprocess
class Joystick:
"""Initializes base class and launches jstest and xboxdrv"""
def __init__(self, refreshRate=2000, deadzone=4000):
self.proc = subprocess.Popen(['xboxdrv', '-D', '-v', '--detach-kernel-driver', '--dpad-as-button'], stdout=subprocess.PIPE, bufsize=0)
self.pipe = self.proc.stdout
self.refresh = refreshRate
self.refreshDelay = 1.0 / refreshRate
self.refreshTime = 0 # indicates the next refresh
self.deadzone = deadzone
self.start()
self.xbox = subprocess.Popen(['jstest', '--normal', '/dev/input/js0'], stdout=subprocess.PIPE, bufsize=-1, universal_newlines=True)
self.response = self.xbox.stdout.readline()
a = Thread(target=self.reload2())
a.start()
print("working")
def reload2(self):
while True:
self.response = self.xbox.stdout.readline()
print("read")
time.sleep(0.5)
def start(self):
global leftVibrateAmount, rightVibrateAmount
leftVibrateAmount = 0
rightVibrateAmount = 0
readTime = time.time() + 1 # here we wait a while
found = False
while readTime > time.time() and not found:
readable, writeable, exception = select.select([self.pipe], [], [], 0)
if readable:
response = self.pipe.readline()
# tries to detect if controller is connected
if response == b'[ERROR] XboxdrvDaemon::run(): fatal exception: DBusSubsystem::request_name(): failed to become primary owner of dbus name\n':
raise IOError("Another instance of xboxdrv is running.")
elif response == b'[INFO] XboxdrvDaemon::connect(): connecting slot to thread\n':
found = True
self.reading = response
elif response == b'':
raise IOError('Are you running as sudo?')
if not found:
self.pipe.close()
# halt if controller not found
raise IOError("Xbox controller/receiver isn't connected")
循环被定义为在 __init__ 函数中开始运行,如下所示:
a = threading.Thread(target=self.reload2) # code hangs here
a.start()
但是每次我创建变量“a”时,整个程序都会挂在while循环中,应该在另一个线程中运行。
感谢您的帮助。
【问题讨论】:
-
它挂在线程的创建上,在你开始之前?
-
是的,如果我将
print("test")放在a.start()之前,它不会被打印出来,所以我认为它会在创建线程时挂起。 -
你是怎么发现它被屏蔽的? self.xbox.stdout.readline() 是阻塞调用吗,而您正在 main 中执行其他您看不到的操作?
-
是的,我尝试在其后面添加打印,但它不打印任何内容。使用此模块的程序也挂起。
-
要放入
__init__的代码有很多。我建议您删除除简单变量声明之外的所有内容,并将其余部分放入显式调用的start()方法中。
标签: python while-loop module