Threading модулінің функциясы
Осында қолданылатын threading модулінде ағындар жайлы ақпаратты алуға мүміндік беретін функциялар бар:
· activeCount(). қазіргі уақытта Thread классының данасының белсенді санын қайтарады.Нақты түрде, бұл len(threading.enumerate()).
· currentThread(). Ағымдағы обьект-ағынын қайтарады, яғни осы функцияны шақырған, басқару ағынына сәйкес. Егер ағын threading модуль арқылы құрылмаса, қысқартылған функционалдылық(dummy thread object) обьект-ағынымен қайтарылатын болады.
· enumerate(). Белсенді ағындар тізімін қайтарады. Аяқталған және әлі басталмаған ағындар тізімге кірмейді.
Thread классы
threading.Thread классының даналары Python-бағдарламасының ағындарын ұсынады. Ағында орындалатын әрекеттерді екі тәсілмен беруге болады: орындалатын обьект классының конструкторын жіберу және оған аргументтер немесе мұралану көмегімен анықталған run() әдісімен берілген жаңа класс алу. Бірінші тәсіл жоғарыдағы мысалда қарастырылған. threading.Thread класс конструкторы келесідей аргументтерге ие:
Thread(group, target, name, args, kwargs)
Мұндағы group – ағындар жиынтығы (әзірге қолданылмайды, None тең болу керек), target - run() әдісінде шақырылатын обьект, name – ағын атауы, args және kwargs – target обьекті параметрінде берілгендерді шақыру үшін позициялық және аттаулық параметрлердің (сәйкесінше) тізбектілігі және сөздігі. Жоғарыда келтірілген мысалда тек позициялық параметрлер қолданылған, бірақ дәл солай аттаулар параметрін қолдануменде орындауға болатын еді:
import threading
def proc(n):
print "Процесс", n
p1 = threading.Thread(target=proc, name="t1", kwargs={"n": "1"})
p2 = threading.Thread(target=proc, name="t2", kwargs={"n": "2"})
p1.start()
p2.start()
Дәл солай threading классынан мұрагерлік арқылы жасауға болады. Жекеменшік конструкторын және run() әдісінің анықталуымен берілген Thread:
import threading
class T(threading.Thread):
def __init__(self, n):
threading.Thread.__init__(self, name="t" + n)
self.n = n
def run(self):
print "Процесс", self.n
p1 = T("1")
p2 = T("2")
p1.start()
p2.start()
Ең бірінші конструкторда жасау қажет – базалық класстың конструкторын шақыру. Бұрынғыдай ағынды іске қосу үшін, run() әдісінде әрекеттің орындалуына әкелетін, обьект-ағынының start() әдісін орындау қажет.
Өмірлік ағындарды келесі әдістер арқылы шақыра отырып басқаруға болады:
· start(). Ағынға өмір береді.
· run(). Бұл әдіс ағында орындалуға тиіс әрекеттерді ұсынады.
· join([timeout]). Осы ағынды шақыратын ағын шақырылған әдіс бойынша ағынның аяқталуын күте отырып тоқтатылады. timeout параметрі (жылжымалы нүктемен берілген сан) күту уақытын көрсетуге мүмкіндік береді (секундпен), жарамдылығы біткен соң, қайсыбір join әдісі шақырылған, ағынның аяқталуына қарамастан тоқтатылған ағын өз жұмысын жалғастырады. Кейбір ағынның join() көп рет шақыруға болады. Ағын өз-өзін шақыра алмайды. Жәнеде әлі іске қосылмаған ағынның аяқталуын күтуге болмайды. "join" сөзін ағылшыншадан аударған кезде байланыстыру деген мағынаға ие, яғни join() шақырушы әдіс, ағын аяқталған соң ағынды шақыру әдісіне байланысқанын қалайды.
· getName(). Ағын атауын қайтарады. Басты ағын үшін бұл "MainThread".
· setName(name). Ағынға name атауын меншіктейді.
· isAlive(). Егер ағын жұмыс істесе, ақиқатын қайтарады (run() әдісі шақырылған, бірақ әлі аяқталмады).
· isDaemon(). Егер ағын домен белгісіне ие болса, ақиқатты қайтарады. Python-дағы бағдарлама, демон болып табылмайтын, барлық ағындардың аяқталуы бойынша аяқталады. Негізгі ағын демон болып табылмайды.
· setDaemon(daemonic). Ағын демон болып табылады деген daemonic белгісін орнатады. Бұл белгінің бастапқы мәні мәліметтерді жіберген ағыннан алынады.
Thread модулінде әзірге Java-да ағынға тән мүмкіндіктер іске аспаған (ағындар топтарын анықтау, тоқтату және сыртқы ағындардың үзілуі, басыңқылық және кейбір басқа нәрселер), дегенмен олар келер жылда құрылады.
Таймер
threading.Timer классы берілген уақыт арқылы орындалуы керек әрекеттерін ұсынады. Бұл класс threading.Thread классының ішкі классы болып табылады, сондықтан start() әдісіменде іске қосылады. Келесі стандартты шығаруда Hello, world! басатын қарапайым мысалда айтылғандарды түсіндіреді:
def hello():
print "Hello, world!"
t = Timer(30.0, hello)
t.start()
Лыптар
Қарапайым құлып threading модулінің Lock классы негізінде іске асуы мүмкін. Құлып екі күйге ие: ол ашық тұруы немесе жабық тұруы мүмкін. Соңғы жағдайда оларға кейбір ағындар иелік етеді. Lock классының обьекті келесідей әдістерге ие:
· acquire([blocking=True]). Құлыпты құлыптауға сұраныс жасайды. Егер blocking параметрі көрсетілмесе немесе ақиқат болып табылса, онда ағын құлыптың босауын күтетін болады. Егер параметр берілмесе, онда әдіс мәнді қайтармайды. Егер blocking берілген болса және ақиқат болса, онда әдіс True қайтарады (құлыпты сәтті меңгергеннен кейін). Егер құлыпталу қажет болмаса (яғни blocking=False берілген), әдіс True қайтарады, егер құлып жабылмаса және олармен осы ағын сәтті меңгерген. Кері жағдайда False қайтарылатын болады.
· release(). Құлыпты ашу үшін сұрау.
· locked(). Құлыптың ағындағы күйін қайтарады (True - жабық, False - ашық).
Ескеру керек, тіпті егер құлып күйі жаңа ғана үзілген болсада, ол бұл күйді келесі командаға дейін сақтайды дегенді білдірмейді.
Құлыптың, threading.Lock-тен кейбір ағын оның құлыпталуын көп рет сұрайтындығымен ерекшеленетін, тағы бір нұсқасы бар - threading.Rlock. Бұндай құлыпты құлыптау қанша құлыпталу болды, сонша рет болуы керек. Бұл тиімді болуы мүмкін мысалы, рекурсивті функциялар ішінде.