- 1 1. Mis on Python-i lõimed?
- 2 2. Global Interpreter Lock (GIL) mõistmine Pythonis
- 3 3. Pythoni threading mooduli põhitõed
- 4 4. Lõime loomine Thread klassi alamaklassina
- 5 Thread klassi alamaklassi loomine
- 6 5. Lõimede turvalisus ja sünkroonimine
- 7 6. Lõimed ja I/O-põhised vs CPU-põhised ülesanded
- 8 7. Lõimede haldamine
- 9 8. Lõimede ja multiprocessing mooduli võrdlus
- 10 9. Parimad praktikad lõimede kasutamisel
- 11 10. Kokkuvõte
1. Mis on Python-i lõimed?
Python-i lõimed on mehhanism, mis võimaldab programmil täita mitut ülesannet samaaegselt. Lõimede kasutamine võimaldab programmil käitada erinevaid osi paralleelselt, ilma et üks peaks teist ootama, mis muudab töötlemise efektiivsemaks. Pythonis saab lõimi luua ja hallata, kasutades threading
moodulit.
Lõimede põhikontseptsioon
Lõimed on kerged täitmisseadmed, mis töötavad protsessi sees. Ühes protsessis saab käitada mitut lõime, mis töötavad sõltumatult, võimaldades programmil täita ülesandeid paralleelselt. See on eriti kasulik I/O-operatsioonide (failide lugemine ja kirjutamine, võrgusuhtlus) ning kasutajaliidese reageerimisvõime parandamiseks.
Lõimede kasutamine Pythonis
Näiteks, kui luua veebikraapimise tööriist, saab paralleelselt pääseda mitmele veebilehele, vähendades kogu töötlusaega. Reaalajas andmetöötluse rakendustes võimaldab lõimede kasutamine uuendada andmeid taustal, peatamata peamist protsessi.

2. Global Interpreter Lock (GIL) mõistmine Pythonis
Python-i lõimede puhul on Global Interpreter Lock (GIL) väga oluline mõiste. GIL piirab Pythoni tõlgendajat nii, et korraga saab töötada ainult üks lõim.
GIL-i mõju
GIL takistab lõimede samaaegset töötamist ja tagab protsessi sees mälu haldamise järjepidevuse. Kuid see piirang muudab lõimede kasutamise vähem tõhusaks CPU-mahukates ülesannetes. Näiteks kui mitu lõime üritavad korraga keerulisi arvutusi teha, võimaldab GIL ainult ühel lõimel korraga töötada, piirates jõudluse kasvu.
Kuidas vältida GIL-i piiranguid?
GIL-i piirangutest möödapääsemiseks on soovitatav kasutada multiprocessing
moodulit, mis loob eraldi protsessid. Kuna igal protsessil on oma sõltumatu Pythoni tõlgendaja, saab multiprocessing
abil saavutada tegelikku paralleelsust, mida GIL ei piira.
3. Pythoni threading
mooduli põhitõed
threading
moodul on Pythoni standardraamatukogu, mis võimaldab lõime luua ja hallata. Siin selgitame selle kasutamise põhitõdesid.
Lõime loomine ja käivitamine
Lõime loomiseks kasutatakse threading.Thread
klassi. Näiteks saab lõime luua ja käivitada järgmiselt:
import threading
import time
def my_function():
time.sleep(2)
print("Lõim täideti")
# Lõime loomine
thread = threading.Thread(target=my_function)
# Lõime käivitamine
thread.start()
# Ootame, kuni lõim lõpetab
thread.join()
print("Pealõim lõpetas")
Selles näites luuakse uus lõim, mis täidab my_function
funktsiooni asünkroonselt.
Lõimede sünkroonimine
Lõime lõppu ootamiseks kasutatakse join()
meetodit. See meetod peatab pealõime täitmise seni, kuni teine lõim on lõpetanud, võimaldades lõimede sünkroonimist.

4. Lõime loomine Thread
klassi alamaklassina
threading.Thread
klassi saab alamaklassina laiendada, et luua kohandatud lõimekäitumist.
Thread
klassi alamaklassi loomine
Allpool olev näide näitab, kuidas Thread
klassi alamaklassina luua eraldi lõimeklass ja alistada run()
meetod:
import threading
import time
class MyThread(threading.Thread):
def run(self):
time.sleep(2)
print("Kohandatud lõim täideti")
# Kohandatud lõime loomine ja käivitamine
thread = MyThread()
thread.start()
thread.join()
print("Pealõim lõpetas")
Alamaklassi kasutamise eelised
Alamaklassi kasutamine võimaldab kapseldada lõime täitmise loogikat ja muuta koodi taaskasutatavaks. Samuti on võimalik anda erinevatele lõimedele unikaalsed andmed ja hallata neid paindlikumalt.
5. Lõimede turvalisus ja sünkroonimine
Kui mitu lõime pääseb ligi samale ressursile, on andmete järjepidevuse säilitamiseks vajalik sünkroonimine.
Võistlussituatsioon (Race Condition)
Võistlussituatsioon tekib siis, kui mitu lõime muudavad sama ressurssi üheaegselt, mis võib viia ettearvamatu tulemuseni. Näiteks kui mitu lõime suurendavad loendurit ilma korraliku sünkroonimiseta, võib arvutatud väärtus olla vale.
Sünkroonimine lukustamisega
threading
moodulis on Lock
objekt, mida saab kasutada lõimede sünkroonimiseks. See tagab, et ükski teine lõim ei pääse ressursile ligi enne, kui eelmine on oma töö lõpetanud.
import threading
counter = 0
lock = threading.Lock()
def increment_counter():
global counter
with lock:
counter += 1
threads = []
for _ in range(100):
thread = threading.Thread(target=increment_counter)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print("Lõplik loenduri väärtus:", counter)

6. Lõimed ja I/O-põhised vs CPU-põhised ülesanded
Lõimed on eriti tõhusad I/O-põhiste ülesannete (failioperatsioonid, võrguühendus jne) puhul.
Lõimede eelised I/O-põhiste ülesannete puhul
I/O-põhised ülesanded veedavad suure osa ajast ooterežiimis, seega võimaldab lõimede kasutamine teisi ülesandeid samal ajal täita. Näiteks saab korraga lugeda faile ja suhelda võrgu kaudu, vähendades seisakuid.
CPU-põhised ülesanded ja multiprocessing
CPU-intensiivsete ülesannete puhul on soovitatav kasutada multiprocessing
moodulit, kuna see võimaldab tegelikku paralleeltöötlust ja väldib GIL-i piiranguid.
7. Lõimede haldamine
Siin selgitame, kuidas Pythonis lõime efektiivselt hallata.
Lõimede nimetamine ja tuvastamine
Lõime nime määramine muudab silumise ja logide jälgimise lihtsamaks. Seda saab teha name
argumendiga.
import threading
def task():
print(f"Lõim {threading.current_thread().name} töötab")
thread1 = threading.Thread(target=task, name="Lõim1")
thread2 = threading.Thread(target=task, name="Lõim2")
thread1.start()
thread2.start()
8. Lõimede ja multiprocessing
mooduli võrdlus
Lõimede plussid ja miinused
Lõimed on kergemad kui protsessid ja jagavad mälu, mis teeb need kasulikuks I/O-põhistes ülesannetes. Siiski piirab GIL nende kasutamist CPU-põhistes ülesannetes.
Millal kasutada multiprocessing
moodulit?
Kui ülesanne on CPU-intensiivne, siis multiprocessing
võimaldab kasutada mitut protsessorituuma ja väldib GIL-i mõju.
9. Parimad praktikad lõimede kasutamisel
Lõimede turvaline lõpetamine
Lõime ei tohiks jõuga lõpetada. Selle asemel on soovitatav kasutada lippude või tingimusmuutujate põhist lõpetamist.
import threading
import time
stop_thread = False
def task():
while not stop_thread:
print("Lõim töötab")
time.sleep(1)
thread = threading.Thread(target=task)
thread.start()
time.sleep(5)
stop_thread = True
thread.join()
print("Lõim peatatud")
Surnudlukustuste vältimine
Surnudlukustuste vältimiseks:
- Kasutage lukke järjekindlalt.
- Piirake lukustatud koodi ala nii palju kui võimalik.
- Kasutage
with
konstruktsiooni, et tagada luku vabastamine.
10. Kokkuvõte
threading
moodul on võimas tööriist paralleeltöötluse jaoks. Käesolevas artiklis käsitlesime lõimede põhikasutust, GIL-i mõju, lõimede ja multiprocessing
erinevusi ning parimaid praktikaid.
Lõimed sobivad hästi I/O-põhiste ülesannete jaoks, kuid CPU-intensiivsete tööde korral tuleks kaaluda multiprocessing
mooduli kasutamist. Õige töötlusmeetodi valimine parandab Pythoni rakenduste jõudlust ja töökindlust.