2014-12-15 14 views
7

Chcę wykonać funkcję nieskończonej pętli.Jak korzystać z puli wątków, aby wykonać funkcję nieskończonej pętli?

Oto mój kod

def do_request(): 
    # my code here 
    print(result) 

while True: 
    do_request() 

Kiedy użycie while True to zrobić, to jest trochę powolny, więc chcę używać puli wątków do równoczesnego wykonywania funkcji do_request(). Jak to zrobić ?

Podobnie jak użycie ab (ławka Apache) do testowania serwera HTTP.

+0

Używanie 'concurrent.features'? –

+0

Dziękuję @BhargavRao, będę zobaczyć o dokumencie później. –

+1

Nie umieszczaj odpowiedzi w pytaniu. Jeśli otrzymałeś użyteczną odpowiedź, zaakceptuj ją. Jeśli masz inne pytanie, zadaj je osobno. – jonrsharpe

Odpowiedz

0

Wreszcie, mam rozwiązać ten problem. Używam zmiennej do ograniczenia numeru wątku.

Oto mój ostateczny kod, rozwiązałem mój problem.

import threading 
import time 

thread_num = 0 
lock = threading.Lock() 

def do_request(): 
    global thread_num 
    # ------------- 
    # my code here 
    # ------------- 
    with lock: 
     thread_num -= 1 

while True: 
    if thread_num <= 50: 
     with lock: 
      thread_num += 1 
     t = threading.Thread(target=do_request) 
     t.start() 
    else: 
     time.sleep(0.01) 

Dzięki za wszystkie odpowiedzi.

+0

Gdzie zdefiniowano 'lock'? Ponadto, zamiast ręcznie wywoływać 'lock.acquire' i' lock.release', możesz użyć 'with' block:' with lock: thread_num + = 1' – Kroltan

+0

Przepraszam, zapomniałem. Dodaj to. Kod jest lepszy, dziękuję. –

+0

Nie ma problemu, po prostu czyniąc to odpornym na przyszłość. :) – Kroltan

0

Możesz użyć threading w Pythonie, aby to zaimplementować. Może być coś podobnego do tego (przy użyciu tylko dwa dodatkowe wątki):

import threading 

# define threads 
task1 = threading.Thread(target = do_request) 
task2 = threading.Thread(target = do_request) 

# start both threads 
task1.start() 
task2.start() 

# wait for threads to complete 
task1.join() 
task2.join() 

Zasadniczo, można uruchomić dowolną liczbę wątków, jak trzeba (upewnij się, że nie zbyt wiele, więc system może obsłużyć), następnie należy je odczekać, aż zadania zakończą się.

Lub można uzyskać bardziej zaawansowany z modułem Python multiprocessing.

+0

Dziękuję. Ale nie jest doskonały. Za dużo kodu powtórzeń, jeśli któryś z wątków jest spowolniony, cała pętla będzie na to czekać. Więc myślę, że wykorzystanie puli wątków jest lepsze. Spróbuję zastosować proces wieloprocesowy lub współbieżny. –

+1

To był tylko przykład. Możesz umieścić wszystkie pętle w pętli/tablicy, aby uniknąć powtórzenia kodu, to zależy od Ciebie. Ponadto, jeśli jeden wątek jest wolny, reszta zostanie uruchomiona. Jeden wątek nie spowolni pętli, jeśli uruchomiłeś je wszystkie jednocześnie. Twoja pętla zakończy się, gdy najwolniejszy wątek zostanie wykonany, oczywiście. – nochkin

+0

"Twoja pętla zakończy się, gdy najwolniejszy wątek zostanie wykonany, oczywiście." co jest dokładnie tym, co twierdzi abcfy i czyni to całkiem złym rozwiązaniem (powiedzmy, że jedna prośba wygasa - nagle nic nie robisz przez kilka sekund!). W przypadku "wieloprocesowości" istnieje również klasa threadpool dla starszych wersji, które nie mają nowej nowej równoczesnej klasy. – Voo

0

Wypróbuj poniższy kod:

import multiprocessing as mp 
import time 

def do_request(): 
    while(True): 
     print('I\'m making requests') 
     time.sleep(0.5) 


p = mp.Process(target=do_request) 
p.start() 

for ii in range(10): 
    print 'I\'m also doing other things though' 
    time.sleep(0.7) 

print 'Now it is time to kill the service thread' 
p.terminate() 

The głównych gwiazd nici wątku usługa, która wykonuje żądania i idzie dalej, aż musi, a potem kończy się wątek serwisowym.

+0

Dziękuję. Ale źle rozumiesz. Chcę współbieżnie wykonać '' do_request() '', ponieważ jest trochę powolny. Podobnie jak ab (apache bench) do testowania serwera http. –

+0

Przepraszam, rozumiem, że potrzebujesz wątku usługi. Zostawię odpowiedź tam, na wypadek, gdyby ktoś potrzebujący takiej rzeczy dotarł do twojego pytania przez wyszukiwarki. –

0

Może użyć concurrent.futures.ThreadPoolExecutor

from concurrent.futures import ThreadPoolExecutor 
import time 

def wait_on_b(hello): 
    time.sleep(1) 
    print(hello) # b will never complete because it is waiting on a. 
    return 5 

def wait_on_a(): 
    time.sleep(1) 
    print(a.result()) # a will never complete because it is waiting on b. 
    return 6 


executor = ThreadPoolExecutor(max_workers=2) 
a = executor.submit(wait_on_b, 3) 
b = executor.submit(wait_on_a) 
+0

Dziękuję, zredagowałem moje pytanie. –

0

Jak na ten temat?

from threading import Thread, Event 

class WorkerThread(Thread): 
    def __init__(self, logger, func): 
      Thread.__init__(self) 
      self.stop_event = Event() 
      self.logger = logger 
      self.func = func 

    def run(self): 
      self.logger("Going to start the infinite loop...") 
      #Your code 
      self.func() 

concur_task = WorkerThread(logger, func = do_request) 
concur_task.start() 

Aby zakończyć ten wątek ...

concur_task.stop_event.set() 
concur_task.join(10) #or any value you like 
+0

Dziękuję. Używam zmiennej globalnej, aby ograniczyć numer wątku i rozwiązać mój problem. Możesz zobaczyć mój post. –

Powiązane problemy