1

Я делаю программу, которая управляет двумя двигателями через малину Pi. Я бегу код питона и мне интересно, как добиться следующего:Ждите, пока потоки не закончатся, прежде чем запускать их снова

  • Run MOTOR1
  • Выполнить motor2 одновременно
  • Подождите оба мотора, чтобы закончить
  • Run MOTOR1
  • Выполнить motor2 одновременно
  • и т. Д.

    Что я сделал до сих пор, это создание Thread и использование очереди уе.

    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(), но я не уверен, как правильно ее реализовать. Я также подумал о повторном создании потоков, но не уверен, что это правильное решение.

+0

Пожалуйста, исправьте свои отступы, это нарушение, когда другой читает ваш код. –

+0

Где вы удаляете Items из self.q и где вы его инициализируете, как q = Queue() – rocksteady

+0

Да, инициализируется очередь в def __init__: self.q = Queue (maxsize = 0) (каждый поток имеет его собственная очередь); Я также делаю item = self.q.get() в моем методе run(), я обновляю свой код. – batmat

ответ

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) 
+0

Некоторые попытки наконец-то подойдут именно здесь, чтобы убедиться, что замок выпущен. – rocksteady

+0

@rocksteady true. –

+0

Спасибо, я пытаюсь с помощью семафора, но у меня проблемы: - Кажется, что когда я запускаю() поток, потому что очередь пуста, поток останавливается и никогда не запускается снова. (если я вызываю self.run() в setPosition(), например, потоки не будут выполняться одновременно) - Я могу добавить некоторое время (True) в методе run, но тогда нить никогда не остановится и программа никогда не закончится. – batmat

0

Вы можете использовать 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.Thread.join:

Нить может be join() ed много раз.

Для повторного запуска потоков необходимо выполнить повторный инициализацию объекта Thread после каждого запуска.

+0

Он использует соединение, но он не создает Threads заново. – rocksteady

+0

Я не уверен, как «повторно инициализировать объект Thread после каждого запуска». Это просто thread_1 = Stepper (myStepper1) в моем while (loop)? Я не уверен, что это лучшее решение, но опять же я новичок в коде python. – batmat

Смежные вопросы