2016-08-07 14 views
1

Mein Multi-Threading-Skript Erhöhung um diesen Fehler zu töten:Wie Finished Threads in Python

thread.error : can't start new thread 

, wenn es erreicht 460 Themen:

threading.active_count() = 460 

ich die alten Threads übernehmen hält stapeln, da die Skript hat sie nicht getötet. Das ist mein Code:

import threading 
import Queue 
import time 
import os 
import csv 


def main(worker): 
    #Do Work 
    print worker 
    return 

def threader(): 
    while True: 
     worker = q.get() 
     main(worker) 
     q.task_done()   

def main_threader(workers): 
    global q 
    global city 
    q = Queue.Queue() 
    for x in range(20): 
     t = threading.Thread(target=threader) 
     t.daemon = True 
     print "\n\nthreading.active_count() = " + str(threading.active_count()) + "\n\n" 
     t.start() 
    for worker in workers: 
     q.put(worker) 
    q.join() 

Wie töte ich die alten Threads, wenn ihre Arbeit erledigt ist? (Ist die Rückgabe nicht genug?)

+0

'threader' ist eine Endlosschleife .. aber ich sehe nicht, wie Sie hier mehr als 20 Threads erstellen. Erhöht dieser genaue Code diesen Fehler wirklich? – Blorgbeard

+0

Ich rufe main_threader (Worker) von einem anderen Skript normalerweise ohne Threads auf. –

+0

Also, Sie rufen es wiederholt an? OK, gut, wo kommt die "Einfädler" -Funktion jemals raus? 'main' ruft' return' auf, aber das geht einfach zurück auf 'threader', was mit der 'while True'-Schleife fortgesetzt wird. – Blorgbeard

Antwort

0

Ihre threader Funktion wird nie beendet, so dass Ihre Threads niemals sterben. Da Sie nur einen festen Arbeitssatz verarbeiten und nach dem Start keine Elemente hinzufügen, können Sie festlegen, dass die Threads beendet werden, wenn die Warteschlange leer ist.

Siehe folgende geänderte Version des Codes und die Kommentare, die ich hinzugefügt:

def threader(q): 
    # let the thread die when all work is done 
    while not q.empty(): 
     worker = q.get() 
     main(worker) 
     q.task_done()   

def main_threader(workers): 
    # you don't want global variables 
    #global q 
    #global city 
    q = Queue.Queue() 
    # make sure you fill the queue *before* starting the worker threads 
    for worker in workers: 
     q.put(worker) 
    for x in range(20): 
     t = threading.Thread(target=threader, args=[q]) 
     t.daemon = True 
     print "\n\nthreading.active_count() = " + str(threading.active_count()) + "\n\n" 
     t.start() 
    q.join() 

Beachten Sie, dass ich global q entfernt und stattdessen gebe ich q an die Thread-Funktion. Sie möchten nicht, dass Threads, die durch einen vorherigen Aufruf erstellt wurden, am Ende einen mit neuen Threads teilen (Edit, obwohl q.join() dies sowieso verhindert, es ist immer noch besser, Globals zu vermeiden).

+0

toll, jetzt die Threads stapeln nicht, aber ich arbeite jetzt mit nur 2 Threads? –

+0

Ich vermute, dass deine Arbeit zu schnell geschieht, damit mehr als ein Thread gleichzeitig aktiv sein kann. Da die Warteschlange nun gefüllt ist, bevor die Threads erstellt werden, ist es möglich, dass die ersten beiden Threads die gesamte Warteschlange abschließen, bevor Sie die restlichen Threads erstellt haben. Sie könnten versuchen, 'time.sleep (1)' zur Funktion 'main' hinzuzufügen, um zu sehen, ob Sie mehr simultane Threads sehen. – Blorgbeard

+0

die Hauptfunktion dauert mehr als 1 Sekunde, ist es nicht möglich, dass threading.active_count() auch die fertigen Threads zurückgibt? weil es für jeden neuen Thread inkrementiert. –