
- •Мустафина б.М., Сейдахметова г.Е., Әлібиева ж.М.
- •Пәндік оқу - әдістемелік кешені
- •Алматы 2012
- •1. Пәннің оқу бағдарламасы – syllabus
- •Оқытушылар туралы мәліметтер:
- •1.2 Пән туралы мәліметтер:
- •Оқу жоспарының көшірмесі
- •1.3 Пререквизиттер
- •1.6 Тапсырмалардың тізімі мен түрлері және оларды орындау кестесі
- •1.7 Әдебиеттер тізімі
- •1.8 Білімді бақылау және бағалау.
- •1 Модуль бойынша бақылау жүргізуге арналған сұрақтар (1-7 бөлімдер)
- •2 Модуль бойынша бақылау жүргізуге арналған сұрақтар:
- •1.9 Қойылатын талаптар
- •2 Негізгі таратылатын материалдар мазмұны
- •2.1 Курстың тематикалық жоспары
- •2.2 Лекциялық сабақ конспектілері
- •1.1 Windows ож құрылымы Жүйе құрылымының жалпы бейнелеуі
- •2.2. Ағындарды диспетчерлеу және жоспарлау
- •2.3 Ағынды анықтау
- •2.4 Ағындармен жұмыс істеуге арналған api функциясы
- •2.5 Ағындардың приоритеті
- •3.1 Процесстерді басқару
- •3.2 Windows операциялық жүйесіндегі процесстер мен ағындар
- •3.3 Процесстермен жұмыс істеуге арнлаған api функциялар
- •4.2 Ағындарды синхрондау объектілері
- •Мьютекстер
- •5.1 Оқиғалар
- •5.2 Бұғатталған қосымша функциялар
- •7.1. Үймелер
- •7.2 Үйме жадысын басқару
- •8.1 Файлдар мен каталогтарды басқару Файлдарды құру және ашу
- •8.2 Каталогтарды басқару
- •8.3 Файлдар мен каталогтар атрибуттарын алудың басқа әдістері
- •9.1 Файлдарды бұғаттау
- •9.2 Реестр
- •Экспорттелетін идентификаторды анық қосу
- •12.1 Стандартты құрылғылар және консольді енгізу- шығару
- •12.2 Асинхронды енгізу- шығару және аяқталу порттары
- •2.3 Лабораториялық сабақтардың жоспары
- •2.4 Оқытушының басқаруымен студенттің өзіндік жұмысы бойынша оқу жоспары (соөж) (45 сағат)
- •2.5 Студенттің өзіндік жұмысының сабақ жоспары (сөж) (45 сағат)
- •2.6 Өзін өзі тексеру үшін кілтпен көрсетілген тестік жаттығулар
- •2.7 Курс бойынша емтихан сұрақтары
- •Глоссарий
- •Жүйелік программалау
3.1 Процесстерді басқару
Процесстің құрамында кодасы және деректері бар жекеменшіктік тәуелсіз ауани (виртуалды) кеңістік бар, ол басқа процесстерден қорғалынған. Әрбір процесс өз алдына құрамында бір немесе бірнеше өзалдына тәуелсіз орындалын жатқан ағындар бола алады. Процесс өзінің ішінде жаңа ағындар және жаңа тәуелсіз процесстер құра алады және хабарды басқара алады және объектілерді синхрондай алады.
Қосымшалар процесстерді құра отырып және оларды басқара отырып біруақытта файлдарды өңдеу бойынша есептерді орындап, есептеулерді жүргізіп және желідегі басқа жүйелермен өзараәрекететсе алады. Өңдеуді жылдамдату мақсатында бірнеше процессорды қолдану мүмкіндігі бар.
3.2 Windows операциялық жүйесіндегі процесстер мен ағындар
Әрбір процесстің құрамында бір немесе бірнеше ағын бар. Windows операциялық жүйесіндегі ағын дегеніміз — орындалудың негізгі бірлігі.
Программист тұрғысынан Win32 жүйесіндегі әрбір процесстің құрамында төменде көрсетілген компоненталар бар:
Бір немесе бірнеше ағындар;
Басқа процесстердің адрестік кеңістіктерінен өзге ауани адрестік кеңістік, бұл жағдай жадыны нақты бөлу жағдайына қатысты емес. Жадыда көрінетін файлдар физикалық жадыдан орын алғанымен, әртүрлі процесстер жадыда көрінетін файлдарға әртүрлі ауани адрестерді қолданады:
DLL кодамен қоса бір немесе бірнеше кода сегменттерін;
ауқымды айнамалылардан тұратын бір немесе бірнеше деректер сегменттерін; ортамен (окружения) байланысты айнымалылыр туралы ақпараты бар орта қатарлары, мысалыіздестірудің ағынды жолы.
• процесс үймелері жадысы.
• ашық дескрипторлар немесе басқа үймелер сияқты ресурстар.
Процесстің барлық ағындары кодаларды, ауқымды айнымалыларды, орта (окружения) қатарларын және ресурстарды ортақ түрде қолданады. Әрбір ағын тәуелсіз түрде жоспарланады. Ағын құрамына төменде келтірілген элементтер кіреді:
процедураларды, үзулерді, алып тастауларды (исключений) өңдеуді және автоматтық деректерді шақыру стегі;
ағынның жергілікті жадысы (Thread Local Storage — TLS) — көрсеткіштер (сілтемелер) массивы, олар процесске жекеменшіктік ерекше орта (окружения) деректерін қалыптастыру үшін жады бөлуге мүмкіндік береді;
деректер қалыптастырған ағыннан алынған стек параметрі, ол әдетте әр ағын үшін ерекше болып табылады;
құрамында аппараттық регистрлердің мәндері бар контекст құрылымы. Ол ядромен басқарылады.
3.1-суретте бірнеше ағындары бар процесс көрсетілген. Бұл схематикалық бейнелеуде жадының нақты адрестері және масштаб көрсетілмеген.
3.3 Процесстермен жұмыс істеуге арнлаған api функциялар
Процесстерді қалыптастыру
Windows жүйесінде жаңа процесс прототипі төменде көрсетілген createProcess функциясын шақыру арқылы қалыптасады:
BOOL CreateProcess(
LPCTSTR lpApplicationName, // атқарылатын модулдің атауы
LPTSTR lpCoramandLine, // командалық қатар
LPSECURITY_ATTRIBUTES lpProcessAttributes, // процессті қорғау
LPSECURITY_ATTRIBUTES lpThreadAttributes, // ағынды қорғау
BOOL bInheritHandles, // дескрипторды иемдену белгілері
DWORD dwCreationFlags, // процессті жасау белгілері
LPVOID lpEnvironment, // жаңа орта (окружения) блогы
LPCTSTR lpCurrentDirectory, // ағынды каталог
LPSTARTUPINFO lpStartUpInfo, // негізгі терезе түрі
LPPROCESS_INFORMATION lpProcessInformation // процесс
// туралы ақпарат );
CreateProcess функциясы процесс және ағын сәтті қалыптасқан болса TRUE мәнін қайтарады, сәтсіздік жағдайында FALSE мәнін қайтарады. Жаңа процесс қалыптастыратын процесс аталық (parent process) деп аталады. Басқа процес арқылы қалыптасқан жаңа процесс бағынқы (child process) деп аталады. CreateProcess функциясының кейбір параметрлерін баяндайық. Бірінші параметр – lpApplicationName – қатарды ехе типтік атқарылушы файлдың атымен анықтайды, және ол жаңа процесс қалыптасқанда іске қосылады. Бұл қатар нөлмен аяқталуы керек және атқарылушы файлға апаратын толық жоды кқрсету керек. Қайтарылатын мән:
lpCommandLine параметрін қолданғанда жүйе жаңа процессті іске қосуы үшін қажетті ехе-файлды іздестіруді бастайды, іздестіру жүргізілетін каталогтар тізімі төменде көрсетілген:
- қосымша іске қосылған каталог;
- аталық процесстің ағынды каталогы;
- Windows-тың жүйелік каталогы;
- Windows каталогы;
- ортаның PATH айнымалысында тізімделген каталогтар.
lpProcessAttributes және lpThreadAttributes параметрлері процесс пен ағынның қауіпсіздік атрибуттарының құрылымына көрсетеді. Егер олардың мәндер NULL болса, атрибуттар үнсіздік бойынша қолданылады.
bInheritHandles параметрі жаңа процесс ашық функцияны шақырушы процесстің иемделінетін дескрипторларының (файлдардың, бейнелеулердің және т.б.) көшірмесін иемделуі керектігін немесе керек емес екенін анықтайды. Иемделінген дескриторлар өздерінің түпнұсқаларындағыдай (оригинал) атрибуттардан тұрады.
dwCreationFlags параметрінде бірнеше белгілерді біріктіруге болады.
CREATE_SUSPENDED — бастапқы ағын, ол күту күйінде болады және тек ResumeThread функциясын шақырғаннан кейін ғана іске қосылады.
DETACHED_PROCESS және CREATE_NEW_CONSOLE — өзара алып тастаушы белгілер; бұлардың екеуінде бір уақытта орнатуға болмайды. Бірінші белгі процессті консолсыз қалыптастырады, екіншісі жаңа процесске консоль ұсынады. Ешер осы екі белгілердің бірі орнатылмаған болса, процесс аталық процесстің консольін иемденеді.
CREATE_NEW_PROCESS_GROUP —жаңа процесстер тобы үшін жаңа процессті түпкі (корневой) етіп анықтайды. Егер топтағы процесстер бірігіп бір консольді қолданса, онда олар консольді басқару сигналын қабылдайды.
Кейбір белгілер жаңа процесс ағынының приоритетін басқарады. Әзірше аталық процесстің приоритетін немесе NORMAL_PRIORITY_CLASS мәнін қолданамыз.
lpEnvironment жаңа процесс үшін орта (окружения) блогын көрсетеді. Егер параметр NULL мәніне ие болса, онда аталық процестің ортасын (окружения) қолданады.
lpCurrentDirectory жаңа процесс үшін диск және каталог анықтайды. Егер оның мәні NULL болса, онда аталық процесстің жұмысшы каталогы қолданылады.
lpStartUpInfo жаңа процесс үшін стандарттық құрылғылардың программалар мен дескрипторларының негізгі терезелерін көрсетеді.
lpProcessInformation параметрі қалыптасқан процеске және ағынға арналған дескрипторлар мен идентификаторлар орналасатын құрылымды анықтайды. ROCESS_INFORMATION құрылымы келесідей анықталады:
typedef struct _PROCESS_INFORMATION { HANDLE hProcess;
HANDLE hThread; DWORD dwProcessID; DWORD dwThreadID;
} PROCESS_INFORMATION;
Процесстің аяқталуы
Процесс жұмысын ExitProcess функциясын шақыру арқылы аяқтай алады, оның прототипі төменде көрсетілген:
VOID ExitProcess(
UINT uExitCode // процесстен қайтару кодасы );
ExitProcess функциясын шақырған кезде процесстің барлық ағындары қайтару кодасымен аяқталады, қайтару кодасы осы функцияның параметрі болып табылады. Бұл функцияны орындаған кезде жүйе процесспен жүктелген динамикалық кітапханаларға DLL_PROCESS_DETACH хабарын жібереді, бұл хабар динамикалық кітапхананы процесстен ажырату керектігін білдіреді.
Бір процесс басқа процестің көмегімен TerminateProcess функциясын шақыру арқылы аяқтала алады, оның прототипі келесідей:
BOOL TerminateProcess(
HANDLE hProcess, // процесс дескрипторы
UINT uExitCode // қайтару кодасы );
Егер TerminateProcess функциясы сәтті орындалса, нөльдік емес мән қайтарылады, қарсы жағдайда - FALSE. TerminateProcess функциясы процесс жұмысын аяқтайды, бірақ осы процесске қатысты ресурстарды босатпайды, өйткені жүйе процесспен жүктелген динамикалық кітапханаларға кітапхананы процесстен ажырату туралы хабарды жібермейді. Сондықтан бұл функция процесс тоқтап қалған төтенше жағдайларда ғана шақырылуы тиіс.
Процесстерді идентификациялау
Процесс жаңа бағыңқы (дочерный) процесстің идентификаторы мен дескрипторын PROCESS_INFORMATION құрылымынан ала алады. Бағыңқы процесстің дескрипторын жабу оған аталық процесстің қатынас құру мүмкіндігін ғана жояды. Бұл процесстің баяндамасын алу үшін келесі жұп функциялар қолданылады.
HANDLE GetCurrentProcess (VOID)
DWORD GetCurrentProcessId (VOID)
GetCurrentProcess функциясы шын мәнінде иемделінбейтін псевдодескрипторды қайтарады. Бұл мән процесске өзінің жеке дескрипторы керек кезде қолданылады. Қайтарылған GetCurrentProcessId функцияның мәнін OpenProcess функциясын шақырылымында қолдана отырып, оның ID арқылы процесстің нағыз дескриторын қалыптастырыңыз.
HANDLE OpenProcess ( DWORD fdwAccess, BOOL fInherit,
DWORD IDProcess)
Қайтарылатын мән: процесс дескрипторы немесе қате болған жағдайда NULL мәні.
fdwAccess параметрі процесстің дескриторға қатынас құру параметрін анықтайды. Оның мүмкін болатын кейбір мәндерін келтірейік.
SYNCHRONIZE белгісі басқа процесстерге күту функциясын қолдана отырып осы процессті күтуге рұқсат береді;
OCESS_ALL_ACCESS — қатынас құрудың барлық белгілері орнатылған;
PROCESS_TERMINATE белгісі TerminateProcess функциясын шақыру арқылы процесстің аяқталуына мүмкіндік береді;
PROCESS_QUERY_INFORMATION белгісі GetExitCodeProcess функциясы арқылы дескрипторды қолдануға рұқсат береді және GetPriorityClass функциясы арқылы процесс туралы ақпарат алуға рұқсат береді.
Орындалушы процесс өзінің жүктеуші файлының атауын GetModuleFileName функциясы көмегімен анықтай алады, бұл жағдайда hModule параметрі ретінде NULL көрсеткіші қолданылады. Бұл функцияны динамикалық кітапханадан шақыру кітапханамен қолданылатын .ЕХЕ файлды емес, DLL файлының атауын.
Дескрипторларды көшіру
Аталық және бағыңқы процесстерге бағыңқы процесстен иемделінген дескриптор арқылы анықталатын объектіге қатынас құру үшін түрлі қатынас құрулар қажет болуы мүмкін. Сондай ақ, процесске бағыңқы процестің қолдануына арналған GetCurrentProcess функциясы арқылы қалыптасқан псевдодескриптоордың орынын нағыз дескриптор керек болуы мүмкін. Бұл мәселені шешу үшін аталық процесс дескриптордың қажетті қатынас құру және иемдену түрлеру бар көшірмелерді қалыптастыруы керек. Төменде дескрипторларды көшіруге арналған функциялар келтірілген:
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle, // таратушы (источник) процесс
// дескрипторы
HANDLE hSourceHandle, // бастапқы дескриптор
HANDLE hTargetProcessHandle, // қабылдаушы процесс
// дескрипторы
LPHANDLE lpTargetHandle, // бастапқы дескриптор дубликаты
DWORD dwDesiredAccess, // объектіге қатынас құру
// белгілері
BOOL bInheritHandle, // дескрипторды имедену
DWORD dwOptions // қосымша мінетті емес белгілер );
Егер DuplicateHandle функциясы сәтті аяқталса, онда ол нөлдік емес мәнді қайтарады. Қарсы жағдайда FALSE мәні қайтарылады.
Негізгі әдебиеттер: 1 [58 - 93], 2 [167 - 179]
Бақылау сұрақтары:
Ағындарды жоспарлау қандай факторлар негізінде жүргізіледі?
Win32 жүйесінде қандай компонеталар әрбір процессті қосады?
Ағын құрамында қандай элементтер бар?
OpenProcess() функциясының API параметрлері.
Дәріс 4. Ағындарды синхрондау.
Ағындар программаны өңдеуде және құрастыруда жұмысты жеңілдетеді, сонымен қатар жылдамдығын жоғарлатады. Көбінесе екі немесе одан көп ағындарды сол мезетте орындалып жатқан кезде координациялау үшін қажеттіліктер туады.
Мысалы, бірнеше ағындар бір айнымалыға қатынау кезінде болады. Ал басқа жағдайларда бір ағын, басқа бір ағынның жұмысы аяқталмайынша, ол өзінің жұмысын жалғастыра алмайды. Міне, осындай жағдайларда синхрондау қажеттіліктері туады.
Синхрондау объектілері және күту функциялары.
Windows операциялық жүйелерінде синхрондау объектілері деп сигналдық (signaled) және сигналдық емес (nosignaled) екі күйдің бірінде бола алатын ядро объектілерін атайды. Синхрондау объектілері төрт класқа жіктелуі мүмкін.
Бірінші класқа синхрондау объектілерінің өзі, яғни параллелдік ағындарды синхрондау мәселелерін шешуге ғана арналған объектілер жатады. Windows операциялық жүйелерінде мұндай объектілерге келесілер жатады:
мьютекс (mutex);
оқиғалар (event);
семафор (semaphore).
Синхрондау объектілерінің екінші класына берілген уақыт интервалы өткеннен кейін сигналдық күйге ауысатын күтуші таймер (waitable timer) жатады.
Синхрондау объектілерінің үшінші класына өзінің жұмысы аяқталған соң сигналдық күйге ауысатын объектілер жатады:
жұмыс (job);
үрдіс (процесс) (process);
ағын (thread).
Синхрондау объектілерінің төртінші класына объект құрамындағылар өзгергені туралы хабар алған соң сигналдық күйге ауысатын объектілер жатады, олар:
каталог күйін өзгерту (change notification);
консолдық енгізу (console input).
4.1 Күту функциялары. Windows-тағы күту функциялары дегеніміз – ол параметрлері синхрондау объектілері болып табылатын функциялар. Бұл функциялар әдетте ағындарды бұғаттау (блокировка) үшін қолданылады. Ағындарды тосқауылдау келесідей орындалады. Егер синхрондау объектісінің дескрипторы күту функциясының параметрі болып табылса, ал синхрондау объектісінің өзі сигналдық емес күйде болса, онда осы күту функциясын шақырушы ағын синхрондау объектісі сигналдық күйге ауысқанша тосауылданады. Қазір біз тек екі күту функциясын ғана қарастырамыз: WaitForSingleObject және WaitForMultipleObject.
WaitForSingleObject функциясы. Бір синхрондау объектісінің сигналдық күйге ауысуын күту үшін WaitForMultipleObject функциясын қолданамыз, ол келесідей түрде болады:
DWORD WaitForSingleObject(
HANDLE hHandle, // объект дескрипторы
DWORD dwMilliSeconds // миллисекундпен берілген күту интервалы);
WaitForSingleObject функциясы dwMilliSecons параметріне тең уақыт интервалы ішінде дескрипторы hHandle параметрімен берілетін синхрондау объектісінің сигналдық күйге ауысуын күтеді. Егер dwMilliSecons парметрінің мәні нөлге тең болса, онда функция тек синхрондау объектісінің күйін ғана тексереді. Егер dwMilliSecons парметрінің мәні INFINITE мәніне тең болса, онда функция синхрондау объектісінің сигналдық күйге ауысуын шексіз ұзақ күтеді.
WaitForSingleObject функциясы сәтті орындалған жағдайда келесі мәндердің бірін қайтарады:
WAIT_OBJECT_0 - объект сигналдық күйге ауысты;
WAIT_ABBANDONED - ұмытылған мьютекс;
WAIT_TIMEOUT - күту уақыты бітті.
WAIT_OBJECT_0 мәні – синхрондау объектісінің сигналдық күйде болғанын немесе сигналдық күйге ауысқанын білдіреді.
WAIT_ABBANDONED мәні синхрондау объектісі ретінде аяқталған ағыннан босамаған мьютекс болғанын білдіреді. Бұл жағдайда мьютекс операциялық жүйемен босатылғандықтан сигналдық күйге ауысады. Мұндай мьютекс кейде ұмытылған немесе тасталынған (abanhoned mutex) мьютекс деп аталады.
WAIT_TIMEOUT мәні күту уақытының біткенін, ал синхрондау объектісінің әлі сигналдық күйге ауыспағандығын білдіреді.
WaitForSingleObject функциясы сәтсіз орындалған жағдайдаWAIT_FALED мәнін қайтарады.
WaitForMultipleObject функциясы. Бірнеше синхрондау объектілерін немесе бірнеше синхрондау объектілерінің ішінен бір синхрондау объектісін сигналдық күйге ауысуын күту үшін келесі прототипте болатын WaitForMultipleObject функциясы қолданылады:
DWORD WaitForMultipleObjects(
DWORD nCount, // количество объектов
CONST HANDLE *lpHandles, // массив дескрипторов объектов
BOOL bWaitAll, // режим ожидания
DWORD dwMilliSeconds // интервал ожидания в миллисекундах );
WaitForMultipleObject функциясы келесідей жұмыс істейді. Егер bWaitAll параметрінің мәні TRUE болса, онда бұл функция, dwMilliseconds параметрінің мәніне тең уақыт интервалы аралығында, дескрипторы lpHandles массивінде берілген барлық синхрондау объектілері сигналдық күйге ауысқанша күтеді. Егер bWaitAll параметрінің мәні FALSE болса, онда бұл функция берілген уақыт интервалы ішінде берілген синхрондау объектілерінің кез келгені сигналдық күйге ауысуын күтеді. Егер dwMilliseconds параметрінің мәні нөлге тең болса, онда функция синхрондау объектілерінің күйін ғана тексереді. Егер dwMilliseconds параметрінің мәні INFINITE болса, онда функция синхрондау объектілерінің синалдық күйге ауысуын шексіз ұзақ күтеді. WaitForMultipleObject функциясымен күтілетін синхрондау объектілерінің саны MAXIMUM_WAIT_OBJECTS мәнінен аспауы керек. Сондай ақ, синхрондау объектілері қайталанбауы керек екендігін ескерте кеткен жөн.
WaitForMultipleObject функциясы сәтті аяқталған жағдайда келесі міәндерді береді:
WAIT_OBJECT_0 мәнінен (WAIT_OBJECT_0 + nCount - 1) мәніне дейін;
WAIT_ABBANDONED_0 мәнінен (WAIT_ABBANDONED_0 + nCount - 1) мәніне дейін;
WAIT_TIMEOUT.
WaitForMultipleObject қайтарушы функциясының интерпретациясының мәні bWaitAll кіріс параметрінің мәніне байланысты. Алдымен бұл параметрдің мәні TRUE болған жағдайды қарастырайық. Онда берілетін мән келесідей интерпретацияланады:
WAIT_OBJECT_0 мәні мен (WAIT_OBJECT_0 + nCount - 1) мәні аралығындағы диапазонында болатын кез келген қайтарылатын мәндер барлық синхрондау объектілері сигналдық күйде болғанын немесе соған ауысқанын білдіреді;
WAIT_ABBANDONED_0 мәні мен (WAIT_ABBANDONED_0 + nCount - 1) мәні аралығындағы диапазонында болатын кез келген қайтарылатын мәндер барлық синхрондау объектілері сигналдық күйде болғанын немесе соған ауысқанын және олардың ең болмаса біреуі ұмытылған мьютекс болғанын білдіреді;
WAIT_TIMEOUT қайтарушы мәні күту уақыты аяқталғанын, бірақ бірде бір синхрондау объектілері сигналдық күйге ауыспағандығын білдіреді.
WaitForMultipleObject функциясы сәтсіз аяқталған жағдайда WAIT_FALED мәнін білдіреді.