
Көп ағынды есептеулер.
Дәрістің мақсаты: Көп ағымды есептеулерді қарастыру, талдау.
Тақырып бойынша қарастырылатын сұрақтар:
1. Басқару ағыны туралы.
2. Threading Модулінің функциялары.
3. Thread Класы.
4. Таймер.
1. Басқару ағыны туралы.
Қазіргі заманғы операциялық жүйеде, тіпті ерекше ештеңе орындамайтын, бір мезгілде бірнеше процесс (processes) жұмыс істей алады. Мысалы, Бағдарламаны іске қосқан кезде жаңа процесс іске қосылады. Процестерді басқару функциялары Python тілінің стандартты os модулінде табуға болады. Мұнда ағындар туралы сөз болады.
Басқару ағындары (threads) бір процесс шеңберінде қалыптасады және жұмыс істейді. Бір ағынды қосымшада (қосымша ағындарды пайдаланбайтын бағдарламада) тек бір ғана басқару ағыны бар. Айтқанда упрощенно, іске қосу кезінде бағдарламаның бұл ағыны дәйекті орындайды встречаемые бағдарламасында операторлар, бағыт ала отыра бірі бойынша баламалы тармақтарының оператордың таңдау арқылы өтеді цикл денесін керегін саны таңдалады орнына өңдеуге алып тастау қозғау кезінде алып тастау. Кез келген уақытта Python интерпретаторы келесі орындау үшін қандай команданы біледі. Команда орындалғаннан кейін қандай командаға басқаруды беретіні белгілі болады. Бұл жіп бағдарламаны орындау барысында үздіксіз және ол аяқталғаннан кейін ғана үзіледі.
Енді бағдарламаның кейбір нүктесінде жіп ажыратылып, әр ағын өз жолымен жүретінін елестете аласыз. Пайда болған ағындардың әрқайсысы одан әрі бірнеше рет үлестірілуі мүмкін. (Бұл ретте ағындардың бірі әрқашан басты болып қалады және оның аяқталуы бүкіл бағдарламаның аяқталуын білдіреді.) Әр уақытта интерпретатор қандай команданы орындау керектігін біледі және әр ағынға уақыт кванттарын бөледі. Мұндай, бағдарламаны орындау тетігінің шамалы күрделенуі іс жүзінде бағдарламада сапалы өзгерістерді талап етеді — өйткені ағындардың қызметі келісілуі тиіс. Ағындарды бір уақытта бір нысанды өзгертіп, осындай өзгерістің нәтижесін, ең алдымен, объектінің тұтастығын бұзуына жол беруге болмайды.
Ағындарды келісудің классикалық құралдарының бірі Семафор деп аталатын объектілер болып табылады. Семафорлар кодтың кейбір бөлігін бірнеше ағындармен бір уақытта орындауға жол бермейді. Ең қарапайым семафор-құлып (lock) немесе mutex (ағылшын тілінен mutually exclusive, өзара ажыратқыш). Ағын кодты орындауды жалғастыру үшін, ол алдымен құлыпты басып алуы керек. Құлыпты басып алғаннан кейін ағын кодтың белгілі бір бөлігін орындайды және содан кейін құлыпты босатады, содан кейін басқа ағынның оны алуы және құлыппен қорғалатын бағдарлама учаскесін одан әрі орындауы үшін. Басқа құлып ағысымен соқтығысқан ағыс, әдетте оның босатылуын күтеді.
Python тілінде көп дәлдікті қолдау бірнеше модульдерді пайдалану арқылы қол жетімді. Threading стандартты модулінде көп ағынды (multithreading) бағдарламаларды әзірлеу үшін қажетті сыныптар анықталған: семафорлардың бірнеше түрі (lock, RLock және semaphore класстары ) және ағындар арасындағы өзара әрекеттесудің басқа механизмдері (Event және Condition класстары ), біраз уақыттан кейін функцияны іске қосу үшін Timer классы. Queue модулі бірден бірнеше ағындарды пайдалана алатын кезекті іске асырады. Thread стандартты модулінде ағындарды құру және (төмен деңгейлі) басқару үшін Thread класы анықталды.
Көп ағынды бағдарламаның үлгісі
Келесі мысалда екі қосымша ағын жасалады, олар әр түрлі стандартты шығаруға шығарылады:
import threading
def proc(n):
print «Процесс», n
p1 = threading.Thread(target=proc, name=»t1″, args=[«1»])
p2 = threading.Thread(target=proc, name=»t2″, args=[«2»])
p1.start()
p2.start()
Алдымен Thread класының екі нысаны алынады, содан кейін түрлі дәлелдермен іске қосылады. Бұл жағдайда ағындарда бір proc () функциясы жұмыс істейді, онда Thread класты конструктордың args атаулы параметрінде берілген бір дәлел беріледі. Start әдісі() жаңа ағысты іске қосу үшін қызмет ететінін болжау қиын емес. Осылайша, келтірілген мысалда үш ағын жұмыс істейді: негізгі және екі қосымша («t1» және «t2» аттарымен).
2. Threading Модулінің функциялары.
Мұнда қолданылатын threading модулінде ағындар туралы ақпарат алуға мүмкіндік бар:
activeCount () қазіргі уақытта Thread класының белсенді даналарының санын қайтарады. Шын мәнінде, бұл len(threading.enumerate ()).
currentThread () ағымдағы нысанды қайтарады-ағын, яғни осы функцияны тудырған тиісті басқару ағыны. Егер ағын threading модулі арқылы құрылмаса, объект-ағын қысқартылған функциясымен (dummy thread object) қайтарылады.
enumerate () белсенді ағын тізімін қайтарады. Аяқталған және әлі басталған ағындар тізімге кірмейді.
3. 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()
3. Таймер.
Threading класы.Timer берілген уақыттан кейін орындалуы тиіс әрекетті білдіреді. Бұл сынып threading Сынып Ішкі сыныбы .Thread, сондықтан start () әдісімен іске қосылады. Стандартты Hello, world тұжырымында басып шығаратын келесі қарапайым мысал! айтқанын түсіндіреді:
def hello():
print «Hello, world!»
t = Timer(30.0, hello)
t.start()