466
Rozdział 11
3
/
4
Musisz pokochtki
execute_slowly(glacial, plodding, leaden)
from threading import Thread
...
t = Thread(target=execute_slowly, args=(glacial, plodding, leaden))
To jest oryginalne
wywołanie funkcji.
Zaimportuj wymagany
moduł i klasę
w okolicach początku
swojego kodu...
...a następnie utwórz nowy obiekt klasy
Thread, który otrzymuje nazwę funkcji do
wykonania, jak również wartości wszystkich
argumentów, których się ona spodziewa.
Jasne, to użycie klasy
Thread
wygląda trochę dziwnie, ale w rzeczywistości takie
nie jest. Kluczem do zrozumienia tego, co się tu dzieje, jest zauważenie, że obiekt
tej klasy został przypisany do zmiennej (którą w naszym przykładzie jest
t
) oraz że
funkcja
execute_slowly
musi się jeszcze wykonać.
Przypisanie obiektu klasy
Thread
do zmiennej
t
przygotowuje tę funkcję do wykonania.
Aby poprosić mechanizm wątków języka Python o wykonanie funkcji
execute_slowly
,
powinieneś uruchomić wątek w taki sposób, jak zostało to pokazane poniżej.
t.start()
Gdy wywołujesz metodę start, wykonanie
funkcji związanej z wątkiem przypisanym
do zmiennej t zostaje zaplanowane przez
moduł threading.
Nie daj się zdołować: użyj wątków
W ogólnym rozrachunku czekanie 30 sekund na zakończenie wykonania funkcji
execute_slowly
nie wydaje się oznaczać końca świata. Jeśli jednak użytkownik
Twojej aplikacji siedzi i czeka, na pewno zacznie się zastanawiać, co poszło nie tak.
Jeśli Twoja aplikacja może kontynuować działanie w czasie, gdy funkcja
execute_slowly
robi swoje, możesz utworzyć obiekt klasy
Thread
, aby wykonać funkcję w sposób
równoległy. Poniżej raz jeszcze możesz zobaczyć zwykłe wywołanie funkcji
execute_slowly
wraz z kodem, który powoduje przekształcenie jej wywołania w żądanie wykonania
w ramach wątku.
W tym momencie kod wywołujący metodę
t.start
kontynuuje swoje działanie.
30-sekundowe opóźnienie związane z wykonaniem funkcji
execute_slowly
nie ma
żadnego wpływu na ten kod, ponieważ wykonanie to jest obsługiwane przez moduł
threading
języka Python, a nie przez Ciebie. Moduł ten „spiskuje” z interpreterem,
aby
ostatecznie wykonać funkcję
execute_slowly
.
jesteś tutaj
467
Trochę tków
Zaostrz ołówek
@app.route(‘/search4’, methods=[‘POST’])
def do_search() -> ‘html’:
phrase = request.form[‘phrase’]
letters = request.form[‘letters’]
title = ‘Oto Twoje wyniki:’
results = str(search4letters(phrase, letters))
try:
log_request(request, results)
except Exception as err:
print(‘***** Logowanie się nie powiodło; wystąpił błąd:’, str(err))
return render_template(‘results.html’,
the_title=title,
the_phrase=phrase,
the_letters=letters,
the_results=results,)
Oto jak
wywołujesz funkcję
log_request w tej
chwili.
Wywołanie funkcji log_request w Twojej aplikacji WWW odbywa się tylko w jednym miejscu i tylko
tam powinieneś go szukać; miejscem tym jest funkcja do_search. Przypomnij sobie, że umieściłeś
już to wywołanie wewnątrz konstrukcji try-except, aby zabezpieczyć się przed wystąpieniem
nieoczekiwanych błędów czasu wykonania.
Zwróć również uwagę, że do kodu funkcji log_request dodałeś 15-sekundowe opóźnienie
korzystając w tym celu z funkcji sleep(15) aby spowolnić jej działanie. Poniżej został przedstawiony
aktualny kod funkcji do_search.
Dodaj kod związany z wątkiem,
którego użyłbyś, aby ostatecznie
wykonać funkcję log_request.
Założymy, że dodałeś już wiersz from threading import Thread na początku kodu swojej
aplikacji WWW.
Weź do ręki ołówek i w pustym miejscu pozostawionym poniżej napisz kod, który wstawiłbyś do
funkcji do_search zamiast standardowego wywołania funkcji log_request.
Pamiętaj, że powinieneś użyć obiektu klasy Thread, aby uruchomić funkcję log_request, tak
jak robiliśmy to z funkcją execute_slowly w przykładzie przedstawionym na poprzedniej
stronie.
468
Rozdział 11
3
/
4
Mechanizm wątków w działaniu
Rozwiązanie
Zaostrz ołówek
Wywołanie funkcji log_request w Twojej aplikacji WWW odbywa się tylko w jednym miejscu i tylko
tam powinieneś go szukać; miejscem tym jest funkcja do_search. Przypomnij sobie, że umieściłeś już to
wywołanie wewnątrz konstrukcji try-except, aby zabezpieczyć się przed wystąpieniem nieoczekiwanych
błędów czasu wykonania.
Zwróć również uwagę, że do kodu funkcji log_request dodałeś 15-sekundowe opóźnienie — korzystając
w tym celu z funkcji sleep(15) aby spowolnić jej działanie. Poniżej przedstawiony został aktualny kod
funkcji do_search.
@app.route(‘/search4’, methods=[‘POST’])
def do_search() -> ‘html’:
phrase = request.form[‘phrase’]
letters = request.form[‘letters’]
title = ‘Oto Twoje wyniki:’
results = str(search4letters(phrase, letters))
try:
log_request(request, results)
except Exception as err:
print(‘***** Logowanie się nie powiodło; wystąpił błąd:’, str(err))
return render_template(‘results.html’,
the_title=title,
the_phrase=phrase,
the_letters=letters,
the_results=results,)
Założyliśmy, że dodałeś już wiersz from threading import Thread na
początku kodu swojej aplikacji WWW.
W pustym miejscu pozostawionym poniżej miałeś napisać kod, który wstawiłbyś
do funkcji do_search zamiast standardowego wywołania funkcji log_request.
Powinieneś był użyć obiektu klasy Thread, aby uruchomić funkcję log_request,
tak jak robiliśmy to z funkcją execute_slowly w poprzednim przykładzie.
Oto jak wywołujesz
funkcję log_request
w tej chwili.
Zostawiamy instrukcję try
w spokoju (na razie).
try:
t = Thread(target=log_request, args=(request, results))
t.start()
except ...
Zestaw klauzuli except
pozostaje bez zmian,
dlatego nie pokazujemy
go tutaj.
Dokładnie tak jak we wcześniejszym przykładzie,
wskaż funkcję, którą należy uruchomić, podaj
wszystkie argumenty, których potrzebuje, i nie
zapomnij o zaplanowaniu uruchomienia swojego
wątku.

Get Python Rusz głową! Wydanie II now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.