#python #multithreading #raspberry-pi #python-multithreading
#python #многопоточность #малина-пи #python -многопоточность
Вопрос:
Я создаю программу, которая управляет 2 двигателями через Raspberry Pi. Я запускаю код на Python, и мне интересно, как добиться следующего :
- Запустите motor1
- Запустите двигатель 2 одновременно
- Дождитесь завершения работы обоих двигателей
- Запустите motor1
- Запустите двигатель 2 одновременно
- и т.д.
То, что я сделал до сих пор, — это создание потока и использование очереди.
class Stepper(Thread): def __init__(self, stepper): Thread.__init__(self) self.stepper = stepper self.q = Queue(maxsize=0) def setPosition(self, pos): self.q.put(pos) def run(self): while not self.q.empty(): item = self.q.get() // run motor and do some stuff thread_1 = Stepper(myStepper1) thread_2 = Stepper(myStepper2) thread_1.start() thread_2.start() loop = 10 while(loop): thread_1.setPosition(10) thread_2.setPosition(30) # I want to wait here thread_1.setPosition(10) thread_2.setPosition(30) loop = loop - 1 thread_1.join() thread_2.join()
И thread_1, и thread_2 не завершатся одновременно в зависимости от количества шагов, которые необходимо обработать двигателю.
Я пытался использовать функциональность Lock(), но я не уверен, как правильно ее реализовать. Я также думал о воссоздании потоков, но не уверен, что это правильное решение.
Комментарии:
1. Пожалуйста, исправьте ваши отступы, это мешает, когда другой читает ваш код.
2. Где вы удаляете предметы из себя. вопрос и где вы его инициализируете, например q = Queue()
3. Да, очередь инициализируется в инициализации def следующим образом: self . q = Queue(maxsize=0) (каждый поток имеет свою собственную очередь); Я также делаю item = self.q.get() в моем методе run(), я обновлю свой код.
Ответ №1:
Вы можете использовать Semaphore
на самом деле:
from threading import Semaphore
class Stepper(Thread):
def __init__(self, stepper, semaphore):
Thread.__init__(self)
self.stepper = stepper
self.semaphore = semaphore
def setPosition(self, pos):
self.q.put(pos)
def run(self):
while not self.q.empty():
try:
# run motor and do some stuff
finally:
self.semaphore.release() # release semaphore when finished one cycle
semaphore = Semaphore(2)
thread_1 = Stepper(myStepper1, semaphore)
thread_2 = Stepper(myStepper2, semaphore)
thread_1.start()
thread_2.start()
loop = 10
for i in range(loop):
semaphore.acquire()
semaphore.acquire()
thread_1.setPosition(10)
thread_2.setPosition(30)
semaphore.acquire()
semaphore.acquire() # wait until the 2 threads both released the semaphore
thread_1.setPosition(10)
thread_2.setPosition(30)
Комментарии:
1. Некоторые try finallys идеально подошли бы здесь, чтобы убедиться, что замок снят.
2. @rocksteady верно.
3. Спасибо, я пытаюсь с помощью семафора, но я сталкиваюсь с проблемами: — Кажется, что когда я запускаю () поток, потому что очередь пуста, поток останавливается и больше никогда не запускается. (например, если я вызову self.run() в setPosition(), потоки больше не будут выполняться одновременно) — я могу добавить while(True) в метод run , но тогда поток никогда не остановится, а программа никогда не завершится.
Ответ №2:
Вы можете использовать метод thread join
следующим образом:
thread_1.join() # Wait for thread_1 to finish
thread_2.join() # Same for thread_2
Согласно документации по адресу https://docs.python.org/3/library/threading.html#threading .Поток.соединение:
Поток может редактироваться
join()
много раз.
Чтобы запускать потоки повторно, вам нужно будет повторно инициализировать Thread
объект после каждого запуска.
Комментарии:
1. Я не уверен, как «повторно инициализировать объект потока после каждого запуска». Это просто thread_1 = Stepper(myStepper1) в моем while(цикл)? Я не уверен, что это лучшее решение, но опять же я новичок в коде Python.