Professional Documents
Culture Documents
3
Wątki w Pythonie
Na podstawie:
Wykładu Marcina Młotkowskiego
oraz
http://docs.python.org
oraz
http://www.tutorialspoint.com/python/python_multithreading.htm
1
Wątek
Wątek (ang. thread) — to jednostka wykonawcza w obrębie jednego procesu, będąca kolejnym
ciągiem instrukcji wykonywanym w obrębie tych samych danych (w tej samej przestrzeni
adresowej). Wątki tego samego procesu korzystają ze wspólnego kodu i danych, mają jednak
oddzielne stosy.
Po co używać wątki
zrównoleglenie wolnych operacji wejścia/wyjścia (ściąganie pliku/obsługa interfejsu)
jednoczesna obsługa wielu operacji, np. serwery WWW
zrównoleglenie czasochłonnych obliczeń numerycznych
2
Prrzykład
dowe ob
bliczeniia programu w
wielowąątkowego
3
Wątki w Pythonie. Moduły
thread (3.0: _thread): niskopoziomowa biblioteka
threading: wysokopoziomowa biblioteka
dummy_thread
Udostępnia duplikat interfejsu do modułu thread. Importowany wtedy gdy moduł tread nie jest
dostępny na platformie
Sugestia zastosowania:
try:
import thread as _thread
except ImportError:
import dummy_thread as _thread
dummy_threading – odpowiednik dummy_thread ale dla modułu threading
4
Wątki w Pythonie. Moduły c.d.
multiprocessing
Pakiet, który wspiera procesy zarządzania wątkami z wykorzystaniem interfejsu API podobnego do
modułu threading. Pakiet multiprocessing oferuje zarówno lokalną i zdalną współbieżność,
skutecznie omijając GIL (Global Interpreter Lock) używając podprocesów zamiast wątków. Ze
względu na to, moduł multiprocessing pozwala programiście w pełni wykorzystać wiele
procesorów na danym komputerze. Działa na systemach Unix i Windows.
5
Moduł thread
Aby rozpocząć nowy wątek:
6
Przykład
#!/usr/bin/python
import thread
import time
while 1:
pass
7
Wynik działania
Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009
8
Moduł threading
Moduł threading
class Thread:
def run(self):
"""Operacje wykonywane w watku"""
def start(self):
"""Wystartowanie obliczen w watku"""
9
Przykład
#!/usr/bin/python
import threading
import time
exitFlag = 0
12
Maraton (przykład)
import threading
Rozpoczęcie biegu:
total_distance = 0
r1 = runner(1)
class runner(threading.Thread):
r2 = runner(2)
def __init__(self, nr_startowy):
r1.start()
self.numer = nr_startowy
r2.start()
threading.Thread.__init__(self)
r1.join()
def run(self):
r2.join()
global total_distance
print ’koniec wyscigu, dystans’,
dystans = 42195
total_distance
while dystans > 0:
dystans = dystans - 1
total_distance = total_distance + 1
if dystans % 10000 == 0:
print ’Zawodnik nr %i’ % self.numer
print ’Zawodnik %i na mecie’ % self.numer
13
Maraton c.d
Rozpoczęcie biegu:
r1 = runner(1)
r2 = runner(2)
r1.start()
r2.start()
r1.join()
r2.join()
print ’koniec wyscigu, dystans’, total_distance
14
Dostęp do wspó lnej zmiennej wątkó w
total_distance = 0
class runner(threading.Thread):
...
total_distance = total_distance + 1
print total_distance
15
Operacje atomowe
i=i+1
LOADFAST 0
LOAD_CONST 1
BINARY_ADD
STORE_FAST 0
16
Blokady
Nowa blokada jest tworzona poprzez wywołanie funkcji Lock() która zwraca nowy obiekt blokadę.
Metoda acquire(blocking=1) obiektu blokady umożliwia synchronizowanie wątków.
Jeżeli parameter blocking ustawiony jest na 0 wątek kończy działanie z wartością 0 jeżeli nie można
założyć blokady oraz zwraca 1 kiedy blokada została założona. Jeżeli blocking jest ustawiony na 1
wątek zakłada blokadę.
Można użyć metody release() do zwolnienia blokady.
lock = Lock()
def run(self):
global lock
...
lock.acquire()
total_distance = total_distance + 1
lock.release()
17
Blokady c.d.
Blokada RLock: Wątek może założyć blokadę dowolną liczbę razy, i tyleż razy musi ją zwolnić.
Bardzo spowalnia program.
Blokada Semaphore: Blokadę można założyć ustaloną liczbę razy.
sem = Semaphore(3)
sem.acquire()
sem.acquire()
sem.acquire()
sem.acquire() # blokada
18
Czekanie na zasó b
Jeden wątek (barman) nalewa mleko do szklanki, drugi (klient) czeka na napełnienie szklanki do
pełna i wypija mleko.
lck = Lock()
# nalewanie
lck.acquire()
for i in range(5):
szklanka_mleka = szklanka_mleka + 1
lck.release()
#wypijanie
import threading
import time
threadLock = threading.Lock()
threads = []
21
Wynik działania programu
Starting Thread-1
Starting Thread-2
Thread-1: Thu Mar 21 09:11:28 2013
Thread-1: Thu Mar 21 09:11:29 2013
Thread-1: Thu Mar 21 09:11:30 2013
Thread-2: Thu Mar 21 09:11:32 2013
Thread-2: Thu Mar 21 09:11:34 2013
Thread-2: Thu Mar 21 09:11:36 2013
Exiting Main Thread
22
Usypianie i budzenie wątkó w
lck = threading.Condition()
# Wypijanie mleka
lck.acquire()
while szklanka_mleka != 5:
lck.wait() #Usypianie
while szklanka_mleka > 0: szklanka_mleka = szklanka_mleka - 1
lck.release()
#Nalewanie mleka
lck.acquire()
for i in range(5):
szklanka_mleka = szklanka_mleka + 1
lck.notify() #budzenie
lck.release()
23
Zmienne warunkowe
Zmienne warunkowe są zmiennymi działającymi jak blokady (aquire(), release());
metoda wait() zwalnia blokadę i usypia bieżący wątek;
metoda notify() budzi jeden z uśpionych wątków (na tej zmiennej warunkowej), notifyAll()
budzi wszystkie uśpione wątki.
Wady mechanizmu
Można nalewać i pić tylko z jednej szklanki.
Barman nie może nalać wiele szklanek na zapas i iść do domu.
24
Wielowątkowa kolejka priorytetó w
Moduł Queue umożliwia tworzenie obiektu kolejki, która może przechować określoną liczbę
elementów.
Poniżej opisano metody zarządzające obiektem Queue:
get() usuwa i zwraca obiekt z kolejki.
put() Dodaje element do kolejki.
qsize() Zwraca liczbę elementów w kolejce.
empty() Zwraca True gdy obiekt jest pusty. W przeciwnym wypadku False.
full() Zwraca True kiedy kolejka jest pełna. False w przeciwnym wypadku
25
Przykład
#!/usr/bin/python
import Queue
import threading
import time
exitFlag = 0
27
# Wait for queue to empty
while not workQueue.empty():
pass
Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
28
Exiting Thread-2
Exiting Main Thread
29