0

직렬 연결에서 데이터를 생성하고 다른 소비자 스레드가 사용할 여러 대기열에 넣는 제작자 스레드가 있습니다. 그러나, 생산자 스레드가 이미 실행을 시작한 후에 주 스레드에서 추가 대기열 (추가 소비자)을 추가 할 수 있기를 원합니다.파이썬에서 실행중인 스레드에서 메소드를 변경하거나 메소드를 호출하는 방법은 무엇입니까?

e.e. 아래의 코드에서이 스레드가 실행되는 동안 주 스레드에서 listOfQueues에 대기열을 추가하는 방법은 무엇입니까? addQueue (newQueue)과 같은 메서드를 추가하여이 클래스에 추가하면 listOfQueues이 될까요? thread가 run 메소드에있을 가능성이 높지는 않습니다. stop 이벤트와 비슷한 이벤트를 만들 수 있습니까?

class ProducerThread(threading.Thread): 
    def __init__(self, listOfQueues): 
     super(ProducerThread, self).__init__() 
     self.listOfQueues = listOfQueues 
     self._stop_event = threading.Event() # Flag to be set when the thread should stop 

    def run(self): 
     ser = serial.Serial() # Some serial connection 

     while(not self.stopped()): 
      try: 
       bytestring = ser.readline() # Serial connection or "producer" at some rate 
       for q in self.listOfQueues: 
        q.put(bytestring) 
      except serial.SerialException: 
       continue 

    def stop(self): 
     ''' 
     Call this function to stop the thread. Must also use .join() in the main 
     thread to fully ensure the thread has completed. 
     :return: 
     ''' 
     self._stop_event.set() 

    def stopped(self): 
     ''' 
     Call this function to determine if the thread has stopped. 
     :return: boolean True or False 
     ''' 
     return self._stop_event.is_set() 
+0

당신은'listOfQueues : q에'자기 자신을 놓쳤습니다. – 101

답변

0

물론, 목록에 추가 기능을 추가하기 만하면됩니다. 예 : 스레드의 start() 메서드가 호출 된 후에도 작동

def append(self, element): 
    self.listOfQueues.append(element) 

.

편집 : 비 스레드 안전 절차 당신이 잠금을 사용할 수 있습니다, 예를 들면 :

def unsafe(self, element): 
    with self.lock: 
     # do stuff 

그런 다음 또한 run 방법 내부의 잠금 장치를 추가해야합니다, 예를 들면 :

with lock: 
    for q in self.listOfQueues: 
     q.put(bytestring) 

잠금을 획득하는 모든 코드는 잠금이 다른 곳에서 해제 될 때까지 대기합니다.

+0

감사합니다. GIL이 있고 기본적으로 쓰레드가 100 개의 명령어를 전환하기 때문에,이 쓰레드가 for 루프의 중간에서 멈추고 메인 쓰레드에서 queue가 self.listOfQueues에 추가되는 경우가있다. 생산자 스레드가 루프의 중간에 있습니까? –

+0

아니요, 'append'는 스레드로부터 안전합니다 : https://stackoverflow.com/a/18568017/1470749. 스레드로부터 안전하지 않은 더 복잡한 프로 시저를 수행하려면 잠금을 사용하여 수행 할 수 있습니다 (편집 참조). – 101

+0

@ThomasJacobs 그런 다음 새로운'Queue'를 별도의'new_queues'리스트에 추가하십시오. 'run' 메소드의'for'-loop 뒤에'newOqueues'를'listOfQueues'에 추가하십시오. –