2012-03-07 2 views
4

다음 코드에 문제가 있습니다. 내 실제 상황에서 SomeClass로 캡슐화 된 로직은 로직을 차단하므로 reactor.callFromThread()으로 호출해야합니다. SomeClass.run()의 루프를 sigint 시그널을 발생 시키면 멈추고 싶다. 나의 이해는 addSystemEvent 훅에서 이것을하기위한 코드를 넣는 것이 이것을 처리해야한다는 것이다. 필자는 이것이 Twisted 자체보다는 파이썬에 대한 이해와 스레딩에 더 많은 문제가 될 것이라고 생각합니다.Twisted에서 스레드를 어떻게 중단합니까?

from twisted.internet import reactor 
import time 

class SomeClass(): 
    def __init__(self): 
     self.running = False 

    def run(self): 
     self.running = True 
     while(self.running): 
      print('foo') 
      time.sleep(5) 

    def stop(self): 
     print('stopping') 
     self.running = False 

someClassInstance = SomeClass() 

def cleanup(): 
    someClassInstance.stop() 

reactor.addSystemEventTrigger('before', 'shutdown', cleanup) 
reactor.callFromThread(someClassInstance.run) 
reactor.run() 

답변

4

Python과 같은 프로그래밍 언어로 스레드를 안전하고 포괄적으로 인터럽트 할 수 없습니다. Java는이 기능을 사용했지만 they removed it은 본질적으로 안전하지 않기 때문에 they removed it입니다. (Java에는 새로운 기능이 있습니다 (Thread.interrupt). 문제가 적은 제한된 버전이지만 여전히 다중 스레드 코드를 작성하는 작업은 복잡합니다.

이 때문에 왜곡 된 스레드는 스레드를 피할 수있는 많은 방법을 제공합니다. 필요하지 않은 경우에는 사용하지 마십시오. 예를 들어, time.sleep(n); foo()을 호출하는 대신 reactor.callLater(n, foo)을 수행하고 callLater이 아직 수행하지 않은 경우 foo의 실행을 쉽게 취소하거나 연기하는 데 사용할 수있는 객체를 반환한다는 점을 제외하면 동일한 효과를 얻습니다.

당신은 당신이 실제로가 시도보다는 '하고 뭔가 일이 "를"time.sleep "를 대체하는지의 예를이 경우에 강론 또 다른 질문을여십시오. 대답은 실제로 에 달려 있습니다. 당신이하고있는 것 - 실제로 시간이 지나요? 다른 프로세스에 대한 I/O 차단? 다른 기계? Twisted는이 모든 것에 적합한 시설을 갖추고 있습니다.

+0

본질적으로 동기식 IMAP 클라이언트 작업을 수행하는 일부 레거시 라이브러리를 호출하여 네트워크 호출을 차단하고 있습니다. 지금은'callFromThread()'대신'callInThread()'를 사용하여 작업하고 있지만, 더 정확한 Twisted 방식으로 내 블로킹 코드를 샌드하는 방법을 알고 싶습니다. 편집 : 나는'deferToThread()'로 더 좋게 보일 수 있다는 것을 깨달았지만 여전히 스레드를 사용하고 있습니다! – Cera

관련 문제