문제

결과를 큐에 쓰는 스레드가 하나 있습니다.

다른 스레드 (GUI)에서는 주기적으로 (유휴 이벤트에서) 대기열에 결과가 있는지 확인합니다.

def queue_get_all(q):
    items = []
    while 1:
        try:
            items.append(q.get_nowait())
        except Empty, e:
            break
    return items

이것이 좋은 방법입니까?

편집하다:

때로는 대기 실이 새로운 결과를 꺼내지 않고 몇 초 동안 붙어 있기 때문에 묻습니다.

"고정 된"문제는 유휴 이벤트 핸들러에서 처리를 수행하고 있었기 때문에 그러한 이벤트가 실제로 호출하여 생성되도록했기 때문입니다. wx.WakeUpIdle, 권장되는대로.

도움이 되었습니까?

해결책

나는 매우 놀랄 것이다 get_nowait() 목록이 비어있는 경우 전화를받지 않으면 전화를 걸지 않아 잠시 멈췄습니다.

수신 스레드에 많은 양의 데이터가 있음을 의미합니다. Queue? 한 번의 배치로 검색 한 숫자를 제한 할 수 있습니다.

def queue_get_all(q):
    items = []
    maxItemsToRetreive = 10
    for numOfItemsRetrieved in range(0, maxItemsToRetreive):
        try:
            if numOfItemsRetrieved == maxItemsToRetreive:
                break
            items.append(q.get_nowait())
        except Empty, e:
            break
    return items

이렇게하면 수신 스레드가 한 번에 최대 10 개의 항목을 가져 오는 것으로 제한됩니다.

다른 팁

항상 사용 가능한 모든 항목을 큐에서 가져 오는 경우 잠금 장치가있는 목록이 아닌 대기열을 사용하는 데있어 실제 사항이 있습니까? 즉:

from __future__ import with_statement
import threading

class ItemStore(object):
    def __init__(self):
        self.lock = threading.Lock()
        self.items = []

    def add(self, item):
        with self.lock:
            self.items.append(item)

    def getAll(self):
        with self.lock:
            items, self.items = self.items, []
        return items

또한 개별적으로 당기고 빈 대기열에 대한 차단 동작을 사용하는 경우 대기열을 사용해야하지만 사용 케이스는 훨씬 간단 해 보이며 위의 접근 방식으로 더 잘 제공 될 수 있습니다.

edit2 유휴 루프에서 대기열을 폴링하고 있다는 사실을 놓쳤으며 업데이트에서 문제가 경합과 관련이 없으므로 아래 접근 방식이 실제로 문제와 관련이 없다는 것을 알았습니다. 누구나이 유용한 차단 변형을 발견 할 경우를 대비하여 남겨 두었습니다.

최소한 하나의 결과를 얻을 때까지 차단하려는 경우 위의 코드를 수정하여 생산자 스레드에 의해 신호를 받음으로써 데이터를 사용할 수있을 때까지 기다릴 수 있습니다. 예를 들어.

class ItemStore(object):
    def __init__(self):
        self.cond = threading.Condition()
        self.items = []

    def add(self, item):
        with self.cond:
            self.items.append(item)
            self.cond.notify() # Wake 1 thread waiting on cond (if any)

    def getAll(self, blocking=False):
        with self.cond:
            # If blocking is true, always return at least 1 item
            while blocking and len(self.items) == 0:
                self.cond.wait()
            items, self.items = self.items, []
        return items

대기열에서 모든 항목을 꺼내는 가장 쉬운 방법은 다음과 같습니다.

def get_all_queue_result(queue):

    result_list = []
    while not queue.empty():
        result_list.append(queue.get())

    return result_list

문서에 따르면 "즉시 사용 가능한 항목을 반환하면 빈 예외를 제기하는 항목"을 사용하는 get_nowait ()를 사용하고 있습니다.

이제 빈 예외가 발생하면 루프에서 벗어나게됩니다. 따라서 큐에 즉시 사용할 수있는 결과가 없으면 기능이 빈 항목 목록을 반환합니다.

대신 get () 메소드를 사용하지 않는 이유가 있습니까? 큐가 동시에 put () 요청을 서비스하기 때문에 get_nowait ()가 실패한 경우 일 수 있습니다.

대기열에 글을 쓰는 경우 QSize는 각 반복에 대한 대기열을 확인하지 않고도 트릭을 수행해야합니다.

responseList = []
for items in range(0, q.qsize()):
    responseList.append(q.get_nowait())

가장 간단한 방법은 목록 이해력을 사용하는 것입니다.

items = [q.get() for _ in range(q.qsize())]

사용 range 기능은 일반적으로 눈살을 찌푸 렸지만 아직 더 간단한 방법을 찾지 못했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top