Два потока, один объект

Я пишу драйвер Linux для устройства USB HID на Python. Устройство имеет два способа отправки данных, оба из которых необходимы: отчеты о функциях (синхронно) и отчеты о входах (асинхронно). Использование библиотеки Cython hidapi У меня есть только один экземпляр устройства для работы, но мне нужно настроить прослушиватель для hid.read(), который будет работать постоянно И разрешать приложению вызывать синхронные методы по желанию для отправки функции отчеты.

В настоящее время у меня есть слушатель в одном потоке и синхронные вызовы в другом. Когда я запускаю программу, мои синхронные вызовы не происходят, хотя они работают нормально, если я никогда не запускаю слушателя; таким образом, кажется, что поток слушателя вступает во владение.

Ниже приведен тревожный фрагмент кода:

app.py

# app.py
import threading
import time
import myhiddriver

# Code that sets mydevice

class Reader:
  def start(self, device):
    self.requests = myhiddriver.DeviceRequest(device)
    # Wait a bit before firing, for testing
    time.sleep(3)
    self.requests.request_swipe_card()

  def start_listener(self, device):
    self.listener = myhiddriver.DeviceListener(device)

reader = Reader()
thread1 = threading.Thread(target=reader.start, args=(mydevice,))
thread1.daemon = True
thread2 = threading.Thread(target=reader.start_listener, args=(mydevice,))
thread2.daemon = True
thread1.start()
thread2.start()

# Keep this puppy running
while True:
  pass

myhiddriver.py

import threading

LOCK = threading.Lock()

class DeviceRequest:
  def __init__(self, device):
    # Lock it up first
    LOCK.acquire()
    self.device = device
    LOCK.release()

  def request_swipe_card(self):
    # Lock this up too
    LOCK.acquire()
    self.device.set_feature_report(insert data here)
    LOCK.release()

class DeviceListener:
  def __init__(self, device):
    # Lock me up
    LOCK.acquire()
    self.device = device
    self.start_listener()
    LOCK.release()

  def start_listener(self):
    while True:
      # Should I be locking this up?
      LOCK.acquire()
      data = self.device.read(255)
      LOCK.release()
      if data:
        print data
      else:
        pass

Мой вопрос: почему мой синхронный вызов (request_swipe_card) не выполняется? Или, как я могу лучше спроектировать это, чтобы иметь бесконечного слушателя И возможность делать синхронные вызовы на одном и том же объекте?

1 ответ

Решение

Судя по всему, это потому, что вы его блокируете

Когда состояние разблокировано, acqu () изменяет состояние на заблокированное и немедленно возвращается. Когда состояние заблокировано, acqu () блокируется, пока вызов release() в другом потоке не изменит его на разблокированный

вот проблема:

class DeviceListener:
  def __init__(self, device):
    LOCK.acquire() # first you lock it up
    self.device = device
    self.start_listener()
    LOCK.release()

  def start_listener(self):
    while True: # because of the loop, the lock wouldn't get release even if the LOCK below doesn't exist
      LOCK.acquire() # it end up blocking here and oops, it locked up xD 
      data = self.device.read(255) # so it wouldn't be able to read here
      LOCK.release()
      if data:
        print data
      else:
        pass

и когда request_swipe_card в конечном итоге вызов в другом потоке, он тоже там блокирует

  def request_swipe_card(self):
    LOCK.acquire() # right here xD
    self.device.set_feature_report(insert data here)
    LOCK.release()
Другие вопросы по тегам