2016-07-19 2 views
0

파이썬 큐가 있습니다.양키에서 요소를 동시에 추가하고 제거하는 방법 (매 x 초마다)?

예를 들어, 1 초마다 양각 큐의 끝에 새로운 요소를 추가하고 싶습니다.

동시에, deque의 첫 번째 요소 (예 : 3 초마다)를 popleft()하고 싶습니다.

시간 기반 프로그래밍을 처음 수행하기 때문에이를 달성하는 방법을 잘 모르겠습니다.

나는 wait()를 사용하는 것에 대해 생각했지만, 이것은 양키에 동시 액세스를 허용하지 않는다는 것을 이해하고있다.

의견이 있으십니까?

도움 주셔서 감사합니다.

+1

파이썬 3.4 이상, 그럴 수 ['asyncio.sleep']을 (사용하는 경우 https://docs.python.org/3/library/asyncio-task .html # asyncio.sleep). – jonrsharpe

답변

0

파이썬에서 동시성을 얻는 방법은 제가 보여주고 자하는 것보다 훨씬 더 정교하고 (적절한) 방법이 있지만 다음과 같은 접근 방식은 매우 간단하고보다 친숙 할 수 있습니다.

n.b. 동일한 시간에 에서 정확히 하나 이상의 연산이 발생할 수 있다는 점에서 이것은 "실제"동시성이 아닙니다. 이것은 파이썬의 GIL로 인해 더 복잡한 방법으로도하기가 어렵습니다.

from collections import defaultdict, deque 
import time 
from datetime import datetime 

class TaskManager: 
    def __init__(self): 
     self.tasks = defaultdict(list) 

    def schedule(self, delta, task): 
     scheduled_at = time.time() + delta 
     self.tasks[scheduled_at].append(task) 

    def tickle(self): 
     now = time.time() 

     keys = list(self.tasks.keys()) 
     for k in keys: 
      if now >= k: 
       for task in self.tasks.pop(k): 
        task() 


def log(msg): 
    print("%s - %s" % (datetime.now().strftime("%M:%S"), msg)) 

tm = TaskManager() 

d = deque() 

# Possible jobs 
def append(): 
    d.append('x') 

    log("Appended: %s" % d) 
    tm.schedule(1, append) 

def popleft(): 
    try: 
     d.popleft() 
    except IndexError: 
     pass 

    log("PoppedLeft: %s" % d) 
    tm.schedule(3, popleft) 


# Schedule initial jobs 
tm.schedule(1, append) 
tm.schedule(3, popleft) 


# Run 
while True: 
    tm.tickle() 
    time.sleep(0.1) 

여기 아이디어는 우리가 보류중인 작업 목록과 각 작업이 실행되어야하는 시간을 유지하는 "작업 관리자"를 가지고있다. 우리는 또한 미래의 어떤 시점에서 우리에게 일자리를 예약하도록 작업 관리자에게 알릴 수 있습니다. 이것은 TaskManager 클래스입니다.

처음에는 작업 관리자 인스턴스와 빈 양단 큐를 만듭니다. 그런 다음 (가변 범위를 악용하여) 작업을 정의합니다. 필자는 append을 deque에 'x'를 추가하고, 빈 상태 일 때 발생하는 오류를 자동으로 무시하여 popleft로 시도하는 popleft을 정의했습니다.

두 작업 모두 실행 후 작업 관리자로 다시 일정을 잡습니다.

마지막으로 작업 관리자를 주기적으로 "간질"하고 작업 목록을 검토하고 작업이 필요한지 확인하기 위해 중단되지 않는 (주) 시작되었습니다. (예정된 시간이 현재이거나 경과 된 경우 작업이 "시작"됩니다).

예제 코드는 약 1/10th 간격으로 실행되지만 더 자주 수행 될 수도 있지만 도 자주 수행하지 않아야합니다. 빈번히 수행해야합니다. 즉, 1/10 초는 시스템 성능에 영향을 미치지 않으면 서 느려질 수있는 것보다 훨씬 느립니다.

샘플 출력 :

 
12:24 - Appended: deque(['x']) 
12:25 - Appended: deque(['x', 'x']) 
12:26 - PoppedLeft: deque(['x']) 
12:26 - Appended: deque(['x', 'x']) 
12:27 - Appended: deque(['x', 'x', 'x']) 
12:28 - Appended: deque(['x', 'x', 'x', 'x']) 
12:29 - PoppedLeft: deque(['x', 'x', 'x']) 
12:29 - Appended: deque(['x', 'x', 'x', 'x']) 
12:30 - Appended: deque(['x', 'x', 'x', 'x', 'x']) 
12:31 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x']) 
12:32 - PoppedLeft: deque(['x', 'x', 'x', 'x', 'x']) 
12:32 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x']) 
12:33 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:34 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:35 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:35 - PoppedLeft: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:36 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:37 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:38 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:38 - PoppedLeft: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:39 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:40 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:41 - PoppedLeft: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:41 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:42 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:43 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:44 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:44 - PoppedLeft: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
12:45 - Appended: deque(['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x']) 
+0

답장을 보내 주셔서 감사합니다. 그냥 질문, 당신은 '스레딩'이 일을 할 수있는 또 다른 옵션, 즉, 하나의 함수 당 하나씩 두 개의 스레드를 가질 수 있다고 생각합니까? – Baalinooo

+0

그럴 것이고, 그 모듈을 보려면 [다중 처리] (https://docs.python.org/2/library/multiprocessing.html) 모듈을 살펴보십시오. – jedwards

관련 문제