2012-08-03 2 views
0

파이썬 대기열에 관해서는 의심 스럽습니다.대기열의 특정 작업이 완료되었는지 확인하는 방법은 무엇입니까?

run() 메서드가 큐를 실행하는 스레드 된 클래스를 작성했습니다.

import threading 
    import Queue 

    def AThread(threading.Thread): 
    def __init__(self,arg1): 
     self.file_resource=arg1 
     threading.Thread.__init__(self) 
     self.queue=Queue.Queue() 

    def __myTask(self): 
     self.file_resource.write() 
     ''' Method that will access a common resource 
      Needs to be synchronized. 
      Returns a Boolean based on the outcome 
     ''' 

    def run(): 
     while True: 
      cmd=self.queue.get() 
      #cmd is actually a call to method 
      exec("self.__"+cmd) 
      self.queue.task_done() 


#The problem i have here is while invoking the thread 
a=AThread() 
a.queue.put("myTask()") 
print "Hai" 

AThread (a = AThread())의 동일한 인스턴스가 다른 위치에서 대기열에 작업을로드합니다.

따라서 하단의 print 문은 위의 명령문을 통해 대기열에 추가 된 작업을 기다린 후 최종 기간 동안 대기해야하며 작업 실행 후 반환 된 값도 수신해야합니다.

이 작업을 수행하는 간단한 방법이 있습니까? 나는 이것에 관해 많은 것을 수색하고,이 코드를 친절하게 검토하고 격렬한 이야기를 제공한다.

왜 파이썬의 획득 및 해제 잠금이 클래스의 인스턴스에 없는지? 언급 된 시나리오에서 AThread의 인스턴스 a와 b는 동기화 될 필요가 없지만 획득 및 릴리스 잠금이 적용될 때 myTask는 a와 b의 두 인스턴스에 대해 동기화되어 실행됩니다.

친절하게 제안합니다.

+1

각 스레드에 대기열이있는 이유는 무엇입니까? – RedBaron

+0

지금 코드를 수정했습니다. b = AThread ("b.txt")를 기다리는 a = Athread ("a.txt")는 myTask 메소드 호출이 서로 다른 두 개의 파일에 있기 때문에 적절하지 않습니다. 따라서 Athread ("a.txt")는 한 번만 호출되고 myTask에 대한 다른 모든 호출은 대기열에 들어갑니다. –

+0

많이 쓰이지는 않지만 대개 대기열은 전역이며 수행 할 작업을 보유합니다. 스레드를 보유하고있는 스레드 풀 (스레드 큐)이 있습니다. 스레드 관리자는 task queu가 비어 있지 않을 때까지 반복됩니다. - 깨어나고, task_queue에서 작업을 가져오고, 스레드 풀에서 스레드를 가져옵니다. 스레드에 작업 할당. 잠자다. 스레드 풀에 스레드가 없으면 잠자기 후 다시 시도하십시오.해당 부분의 스레드 - 결과를 실행하고 반환하면 스레드 풀에 자체가 추가됩니다. 스레드는 서로 독립적으로 작동하지만 모든 작업이 완료 될 때까지 프로그램이 종료되지 않습니다. – RedBaron

답변

0

문제의 특정 윤곽에 따라 취할 수있는 방법이 많이 있습니다.

print "Hai"이 myTask가 완료된 후에 만 ​​발생해야하는 경우 작업에 넣을 수 있으며 myTask가 완료되면 해당 작업을 대기열에 넣을 수 있습니다. (만약 당신이 CS 이론과 같은 사람이라면, 이것을 연속 - 통과 스타일과 유사하다고 생각할 수 있습니다.)

print "Hai"에 여러 작업에 대한보다 정교한 의존성이있는 경우 미래 ​​또는 약속을 조사 할 수 있습니다.

당신은 액터 기반 동시성의 세계로 한 발짝을 옮길 수 있습니다.이 경우, 당신이 원하는 것보다 더 많거나 적은 동기식 메시지 전송 방법이있을 것입니다.

선물이나 약속을 사용하고 싶지 않은 경우 조건 변수를 도입하여 수동으로 비슷한 결과를 얻을 수 있습니다. myTask가 시작되기 전에 조건 변수를 설정하고 myTask로 전달한 다음이 변수가 지워질 때까지 기다립니다. 프로그램이 성장함에 따라 매우 신중해야하며 잠금 전략을 지속적으로 다시 생각하여 간단하고 이해하기 쉽도록 유지해야합니다. 이는 어려운 동시성 버그가 발생하는 것입니다.

원하는 것을 얻는 가장 작은 합리적인 단계는 아마도 조건 변수를 수행하는 Queue.put()의 차단 버전을 제공하는 것입니다. 대기열이 비어있을 때까지 또는 대기열에 넣은 것이 제거 될 때까지 또는 대기열에 넣은 것이 처리를 마칠 때까지 차단할지 여부를 생각하십시오. 그리고 나서 생각할 때 구현하기로 결정한 것을 구현해야합니다.

+0

저는 큐에서 얻는 혜택이 실제로 무엇인지 궁금합니다. 나는 파이썬리스트를 통해 이것을 달성 할 수 있다고 생각한다. 그것은 queue.iscomplete (task) 메소드 bool이 리턴 된 메소드를 가지고 있으면 유용 할 수 있습니다. –

+0

어떻게 스레드가 파이썬에서 객체에 대한 잠금을 획득 할 수 있습니까? –

+0

queue.put()은 threadsafe입니까? list.append()입니까? 나는 그 질문 중 하나에 대한 답을 모른다. 그러나 첫 번째 질문이 예이고 두 번째 질문이 아니오라면 그게 바로 이익이다. 다른 이점은 성능입니다. 한 쪽 끝에 물건을 추가하고 다른 쪽 끝에서 물건을 가져갈 때 대기열이 잘 작동해야하지만, 그 목록을 사용하면 진행중인 많은 복사가 진행됩니다 (기존의 모든 요소는 삽입시 전달되거나 삭제시 모든 요소를 ​​뒤로 이동합니다). – Iain

관련 문제