Запустить бесконечный цикл while в модуле Python - PullRequest
1 голос
/ 27 июня 2019

Я пишу модуль Python, чтобы прочитать вывод jstest и заставить геймпад Xbox работать в Python на Linux.Мне нужно запустить в фоновом режиме бесконечный цикл while в __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, который должен выполняться в другом потоке.

Спасибо за помощь.

1 Ответ

0 голосов
/ 27 июня 2019

У вас могут быть проблемы с вашим __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
read
Введите что-то
1
read

Как вы можете видеть, "Введите что-то" появляется после того, как я добавил поток и запустил его.Это также петли отлично

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...