2017-02-08 1 views
0

설정 : serienchecker.py 파이썬 스레딩이 작동 밤은

import threading 
...other imports ... 

... vars ... 

for drive in drives: 
    series = folder.getFolders(drive) 
    for serie in series:   
     print(str(datetime.datetime.now())) 
     t = threading.Thread(target=serienchecker, args=(drive, serie, blacklist,apikeyv3,language,))   
     t.start() 
     t.join() 

init.py

from threading import Thread 
from themoviedb import * 
from folderhelper import * 
class serienchecker(Thread): 
    ... 
    def __init__(self, path,seriesname, blacklist, apikeytmdb='', language='eng'): 
     ... 
     self.startSearch() 
    ... 

    def startSearch(self): 
     print("start") 
     ... 

출력 :

2017-02-08 21:29:04.481536 
start 
2017-02-08 21:29:17.385611 
start 
2017-02-08 21:30:00.548471 
start 

그러나 내가 그들 모두가 주위에서 계산하려면 같은 시간. 어쩌면 모든 작업을 큐에 대기시키고 N 개의 스레드를 동시에 처리 할 수 ​​있습니까? [이것은 스크립트가 몇 개의 hundert 폴더를 검사하는 작은 예일뿐입니다] 내가 잘못하고 싶습니까?

나는 여러 가지 방법으로 효과를 냈습니다. 도와주세요.

고마워요!

편집 : //

def job(): 
while(jobs): 
    tmp = jobs.pop() 
    task(drive=tmp[0],serie=tmp[1]) 

def task(drive, serie): 
    print("Serie[{0}]".format(serie)) 
    sc = serienchecker(drive, serie,blacklist,apikeyv3,language) 
    sc.start() 
    result = sc.result 
    resultString='' 
    for obj in result: 
     resultString+=obj+"\n" 
    print(resultString) 

for drive in drives: 
    series = folder.getFolders(drive) 
    for serie in series: 
     jobs.append([drive,serie]) 

while(jobs): 
    job() 
+2

왜 모든 스레드가 '시작'한 직후 모든 스레드에 '가입'합니까? 그러면 다른 스레드를 시작하기 전에 스레드가 완료 될 때까지 기다립니다. 또한 스레드의'target'을'Thread'의 하위 클래스로 만드는 것은 말이되지 않습니다. – user2357112

답변

2

join() 대기 스레드가 그래서 당신은 단지 (이전이 끝날 때까지 또는 새 스레드를 만들 수 없습니다) 스레드를 시작한 후 그것을 호출해서는 안 끝날 때까지.
초에 스레드를 저장하는 목록을 작성 : 프로그램의 끝에서

threads.append(t) 

모든 스레드

가입 : 당신이 그들을 만들 때
threads = [] 

가 다음 목록에 스레드를 추가
for t in threads: 
    t.join() 
+0

만약 내가 (단일 스레드)이 내 프로그래머가 작동합니까, 어떻게 스레드 N 개의 금액과 함께 작동하게 만들 수 있습니까? 그래서 그것은 작업 당 1 개의 쓰레드를 사용하려고하지 않습니다. 나는 당신의 방법을 시도했지만, 프로그래머가 추락했고 그는 500 스레드를 넘어서 시작했다. – theunknownsolider

0

이미 언급했듯이 모든 스레드가 시작될 때까지 join을 연기해야합니다. 동시 스레드 수를 제한하는 ThreadPool을 사용하는 것이 좋으며 파이썬의 GIL이 처리 속도를 늦추면 프로세스 풀로 다시 구현할 수 있습니다. 스레드 시작, 디스패치 및 가입을 수행합니다.

import multiprocessing 
import itertools 
import platform 

... 

# helper functions for process pool 
# 
#  linux - worker process gets a view of parent memory at time pool 
#  is created, including global variables that exist at that time. 
#  
#  windows - a new process is created and all needed state must be 
#  passed to the child. we could pass these values on every call, 
#  but assuming blacklist is large, its more efficient to set it 
#  up once 

do_init = platform.system() == "Windows" 

if do_init: 

    def init_serienchecker_process(_blacklist, _apikeyv3, _language): 
     """Call once when process pool worker created to set static config""" 
     global blacklist, apikeyv3, language 
     blacklist, apikeyv3, language = _blacklist, _apikeyv3, _language 

# this is the worker in the child process. It is called with items iterated 
# in the parent Pool.map function. In our case, the item is a (drive, serie) 
# tuple. Unpack, combine w/ globals and call the real function. 

def serienchecker_worker(drive_serie): 
    """Calls serienchecker with global blacklist, apikeyv3, language set by 
    init_serienchecker_process""" 
    return serienchecker(drive_serie[0], drive_serie[1], blacklist, 
     apikeyv3, language) 

def drive_serie_iter(folder, drives): 
    """Yields (drive, serie) tuples""" 
    for drive in drives: 
     for serie in series: 
      yield drive, serie 


# decide the number of workers. Here I just chose a random max value, 
# but your number will depend on your desired workload. 

max_workers = 24 
num_items = len(drive) * len(serie) 
num_workers = min(num_items, max_workers) 

# setup a process pool. we need to initialize windows with the global 
# variables but since linux already has a view of the globals, its 
# not needed 

initializer = init_serienchecker_process if do_init else None 
initargs = (blacklist, apikeyv3, language) if do_init else None 
pool = multiprocessing.Pool(num_workers, initializer=initializer, 
    initargs=initargs) 

# map calls serienchecker_worker in the subprocess for each (drive, serie) 
# pair produced by drive_serie_iter 

for result in pool.map(serienchecker_worker, drive_serie_iter(folder, drives)): 
    print(result) # not sure you care what the results are 

pool.join() 
+0

메신저 프로그래밍과 파이썬에 익숙하지 않은 나는 내 텍스트를 업데이트했다. 나는 pool = multipr ..을 얻는다. 그러나 pool.map (lambda .. part)을 알아낼 수 없다. – theunknownsolider

+0

나는 논평으로 업데이트했고 부팅하는 눈부신 버그를 고쳤다. – tdelaney

관련 문제