Mam wezwanie funkcji w Pythonie, który wygląda tak:

from threading import Thread
while queue:
   Thread(target=queue.extend, args=(longfunction(a, b))).start()

Myślę więc, że kod powyżej działa kilka funkcji queue.extend w równolegle I.E nie czekał aż poprzednia queue.extend wróciła przed rozpoczęciem następnej queue.extend. Ale nie jestem pewien co do argumentów.

Moje pytanie brzmi: Czy Python czeka, aż do pracy (A, B) zakończył ocenę i zwrócono, zanim przenosi się, aby rozpocząć nowy wątek, lub jest cały wątek rozpoczął się od razu, a następnie rozpocznie się następny wątek, zanim LongFunction został zwrócony?

Jestem trochę nowa do wątków, więc proszę wszystko wyjaśnić.

1
user2108462 22 listopad 2013, 03:24

2 odpowiedzi

Najlepsza odpowiedź

Konstruktor Thread to tylko normalne połączenie; Wszystkie jego argumenty, w tym krotka args, muszą być oceniane, zanim można go wywołać.

Tak więc robi to longfunction(a, b) w gwint głównym i wykonuje tylko queue.extend w nitku tła.

Najszybszy sposób naprawienia tego jest utworzenie funkcji wątku za pomocą def lub lambda:

Thread(target=lambda: queue.extend(longfunction(a, b)).start()

Lub alternatywnie:

Thread(target=(lambda x, y: queue.extend(longfunction(x, y)), args=(a, b)).start()

Różnica polega na tym, że pierwszy jest zamknięciem, przechwytywanie {x0}} i b z lokalnego środowiska, więc jeśli zmienili się w czasie, gdy lambda zostanie oceniona, otrzymasz nowe wartości, podczas gdy Drugi nie jest *, więc uzyskanie wartości a i b w momencie powstania Tuple Args. W większości przypadków nie ma znaczenia. Kiedy ma znaczenie, musisz przemyśleć, przez który chcesz.


* Technicznie, zamknięcia i funkcje są tym samym w Pythonie; To tylko zamknięcie bez komórek zamiast jednej z dwoma komórkami w nim.

3
abarnert 21 listopad 2013, 23:38

Tak, poczekać na powrót przed uruchomieniem wątku. Dzieje się tak, ponieważ po dodaniu () do końca funkcji nie jest już odniesieniem do funkcji, jest to połączenie funkcji. Dlatego args=(longfunction(a,b)) zostanie oceniona do args=(return_from_long_function,) w gwintowaniu głównym, wówczas ta wartość zostanie przekazana do celu wątku, w tym przypadku: queue.extend.

0
IT Ninja 21 listopad 2013, 23:29