첫 번째 : 처음에는 유휴 상태에 앉아 배경 스레드가 실제로 필요합니까?
대부분의 플랫폼에서 새 스레드를 시작하는 것은 저렴합니다. (Windows 및 Linux를 제외하고는 슈퍼 치입니다.) 그래서 필요할 때마다 스레드를 시작하지 않는 이유는 무엇입니까? (스레드 목록을 단일 스레드로 유지하는 것만 큼 쉽습니다.)
ThreadPoolExecutor
을 작성하고 작업을 제출하고 실행할 때 걱정할 필요가없는 이유는 무엇입니까? 및 스레드. "작업을 기다려야하는 작업자 스레드"대신 "주 스레드를 차단하지 않고 실행해야하는 작업"이라는 측면에서 생각하면 언제든지 작업을 쉽게 수행 할 수 있습니다. 커버 아래에는 하나 이상의 작업자 스레드가 대기열에서 대기 중이거나 그와 동등한 작업을 수행하지만 그 부분은 모두 작성되고 디버깅되고 최적화되었습니다. 당신이 작성해야하는 것은 단지 정규 기능인 작업입니다.
그러나 명시 적 배경 스레드를 쓰고 싶다면 그렇게 설명 할 수 있습니다.
가 어떻게 CPU 시간을 사용하지 않고 내 작업자 스레드 대기를 할 수 있습니까? ... 작업자 스레드에 신호를 보내는 가장 좋은 방법은 무엇입니까?
값이 준비 될 때까지 스레드를 유휴 상태로 유지하는 방법은 동기화 개체를 기다리는 것입니다. 최신 OS에서 동기화 객체를 기다리면 해당 객체가 준비 될 때까지 CPU 시간을 제공하지 않습니다. *
Threading
모듈 문서에는 다양한 옵션이 있지만 이처럼 대부분의 경우에 사용되는 분명한 것은 Condition
입니다. 작업자 스레드에 신호를 보내는 방법은 notify
Condition
입니다.
그러나 종종 Queue
은 훨씬 간단합니다. Queue
에서 대기하려면 get
메서드를 block=True
으로 호출하면됩니다. 깨어나는 다른 스레드에 신호를 보내려면 Queue
에있는 put
을 입력하십시오. (커버 아래에있는 Queue
은 list
또는 deque
또는 다른 컬렉션 인 Lock
및 Condition
을 감싸며, 원하는 것을 말하면됩니다. 값을 확인하고, 값이 될 때까지 차단하고, 값이있을 때까지 차단하고, 대기 및 시그널링을 처리하고 컬렉션을 보호하는 대신).
작업자 스레드에서 UI 스레드로 또는 그 반대로 양방향으로 신호를 보내는 방법은 controlling UI elements in wxPython using threading의 해답을 참조하십시오.
버튼을 클릭하거나 다른 UI 이벤트가 발생했을 때, 작업자 스레드가 무엇을 변경하라는 지시를 내 렸습니다되도록 내가 UI를 자체 콜백을 등록하는 작업자 스레드에 대한 몇 가지 방법이있을 것이다
그것은하고있다.
원하는 경우이 방법을 사용할 수 있습니다. self.queue.put
또는 def callback(value): self.value = value; self.condition.notify()
또는 콜백으로 전달하십시오. GUI 스레드는 콜백이 다른 스레드를 트리거하고 있음을 알 필요조차 없습니다.
사실 인라인과 백그라운드 스레드간에 앞뒤로 코드를 이동하거나 백그라운드 스레드 대신 자식 프로세스로 이동하기로 결정할 때 매우 행복한 디자인입니다. , 또는 무엇이든.
지금이 권리를 상상할 수 없지만 응용 프로그램은이 일을 실제로 바쁜 동안 작업자 스레드를 신호 할 필요도 더 복잡한을수록 나는 볼 수 있었다.
하지만 바쁠 때는 어떻게되고 싶습니까?
"유휴 상태 일 때 일어나서이 작업을 수행하고, 그렇지 않으면 준비하고 언제든지 수행하십시오"라고 말하면 정확히 Queue
또는 Executor
입니다. 당신을 위해 자동으로하십시오.
"유휴 상태라면 깨우십시오. 그렇지 않으면 걱정하지 마십시오."즉 Condition
또는 Event
이됩니다.
"유휴 상태라면 깨우고 해보십시오. 그렇지 않으면 지금하고있는 일을 취소하고 대신 수행하십시오."라는 말은 조금 더 복잡합니다. 바쁜 동안에 백그라운드 스레드가 주기적으로 "interrupt_me"변수를 확인하고 그 주위에 Lock
을 넣을 필요가 있습니다. 그런 다음 해당 플래그를 설정하고 Condition
을 알리는 것입니다 ... 경우에 따라 유휴 상태 및 통화 중 상태를 단일 작업으로 병합 (유휴 상태 일 경우 무한 wait()
을 호출하고 통화 중일 때는 wait(timeout=0)
을 사용) 단일 Condition
또는 Event
으로 병합합니다. 일부에서
* 경우 - 예 :., 그 좋은 최적화 될 일이 있기 때문에 실제로, 어떤 경우에는 CPU 시간의 조금을 분사 할 수있다 - 그것은 리눅스 futex
또는 Windows CriticalSection
. 그러나 요점은, 당신은 이 아니며, 당신이 그것을 사용할 준비가 될 때까지 어떤 CPU 시간이든을 묻는 것입니다.
"나는 마지막으로 생각해야 할 부분 : ..."섹션을 좋아합니다. –
@PreludeAndFugue : 내가 더 가깝게 이동해야합니까? 나는 이것이 실제로 문제를 해결하는 방법이라고 확신한다. (그의 실제 배경 작업이 무엇인지 알지 못하더라도, "꽤 확실하다"). 그러나 그가 직접 물어 본 것은 아닙니다. – abarnert
예, 그렇게 생각합니다. –