2011-08-02 2 views

답변

-2

폴링에서 select 모듈을 사용하거나 스레드를 사용하여 threading 모듈을 사용하십시오.

+0

Twisted를 이미 사용하고 있다면 나쁜 제안입니다. – Glyph

+2

동료가 이미 뒤틀린 것으로 보입니다. 이런 종류의 일에 왜 나쁜 선택인지 자세히 설명하는 신경? – stderr

8
from twisted.internet.defer import inlineCallbacks, DeferredQueue 

@inlineCallbacks 
def worker(queue): 
    while 1: 
     url = yield queue.get() # wait for a url from the queue 

     if url is None: # insert None into the queue to kill workers 
      queue.put(None) 
      return # done 

     data = yield download(url) # download the file 
     process(data) # do stuff with it 


queue = DeferredQueue() # your queue 

# make workers 
MAX = 20 
workers = [worker(queue) for _ in range(MAX)] 
+0

이 작동하지만 병렬 처리없이 파일을 다운로드합니다. 여러 동시 다운로드를 허용하는 예제를 추가하는 것이 좋습니다. – Glyph

+2

@ 글리프 : 가능한 한 빨리 다운로드하지 않습니다 (작업자는 처리를 기다립니다). 그러나 20 명의 '근로자'로 인해 일부 병렬 처리가 이루어져야합니다. –

+0

죄송합니다. 저기에서 루프를 완전히 놓쳤습니다. 내 의견을 무시하십시오 :). – Glyph

2

여기는 https://github.com/caolan/async을 파이썬으로 번역 한 것입니다.

from twisted.internet import defer 
class Queue: 
    workers = 0 
    tasks = [] 
    def __init__(self, worker, concurrency): 
     self.worker = worker 
     self.concurrency = concurrency 
     self.saturated = None 
     self.empty = None 
     self.drain = None 
    def push(self, data): 
     deferred = defer.Deferred() 
     self.tasks.append({'data': data, 'callback': deferred}) 
     if self.saturated and len(tasks) == concurrency: 
      self.saturated() 
     self.process() 
     return deferred 
    def task_finished(self, *args): 
     self.workers = self.workers - 1 
     if self.drain and len(self.tasks) + self.workers == 0: 
      self.drain() 
     self.process() 
    def process(self): 
     if self.workers >= self.concurrency or len(self.tasks) == 0: 
      return 
     task = self.tasks.pop(0) 
     if self.empty and len(self.tasks) == 0: 
      self.empty() 
     self.workers = self.workers + 1 
     d = self.worker(task['data']) 
     d.addCallback(self.task_finished) 
     d.addCallback(task['callback'].callback) 

from twisted.web import client 
from twisted.internet import reactor 
def dl_worker(data): 
    url = data[0] 
    fname = data[1] 
    print "Download file:", fname 
    d = client.downloadPage(url, fname) 
    return d # very important! 

q = Queue(dl_worker, 2) 
q.drain = reactor.stop 
for i in range(0,3): 
    q.push(["http://download.thinkbroadband.com/5MB.zip", "file"+str(i)]) 
reactor.run() 

Glyph의 QC : D Cheers!

관련 문제