【问题标题】:Run infinite while loop in Python module在 Python 模块中运行无限 while 循环
【发布时间】: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


【解决方案1】:

您的__init__ 可能有问题。我把它放在一个简单的类中作为例子,它按预期运行。

import time
from threading import Thread


class InfiniteLooper():

    def __init__(self):
        a = Thread(target=self.reload2) # reload, not reload(), otherwise you're executing reload2 and assigning the result to Target, but it's an infinite loop, so... 
        print('Added thread')
        a.start()
        print('Thread started')

    def reload2(self):
        while True:
            self.response = input('Enter something')
            print('read')
            time.sleep(0.5)


loop = InfiniteLooper()

输出:

添加线程
话题开始
输入一些东西
1
阅读
输入一些东西
1
阅读

如您所见,“输入内容”在我添加线程并启动后出现。它也循环良好

【讨论】:

  • 我更新了我的帖子并添加了__init__函数的内容。
  • @Astra3 您更新后的代码显示您正在执行a = Thread(target=self.reload2()),但您在它之后的引用显示a = Thread(target=self.reload2)。您是否有可能因为将函数结果分配给目标而不是函数本身而挂起?第二种方式是正确的方式,您更新的代码块中的部分不是。
猜你喜欢
  • 2017-10-12
  • 2020-11-30
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 2012-08-28
  • 1970-01-01
  • 2018-08-30
相关资源
最近更新 更多