Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання icon

Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання




Скачати 208.1 Kb.
НазваМетодичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання
Дата конвертації10.04.2013
Розмір208.1 Kb.
ТипМетодичні вказівки


МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

ЛУЦЬКИЙ НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ





ОПЕРАЦІЙНІ СИСТЕМИ



Методичні вказівки до виконання

самостійної роботи

студентів спеціальності КСМ

денної та заочної форми навчання





РЕДАКЦІЙНО-ВИДАВНИЧИЙ ВІДДІЛ

Луцького національного технічного університету


Луцьк 2009


УДК 004.4

ББК 73Я7

З–46




Операційні системи. Методичні вказівки до виконання самостійної роботи студентів спеціальності КСМ денної та заочної форми навчання. / доц.Бурчак І.Н., Здолбіцький А.П., – Луцьк: ЛНТУ, 2009. – 24с, формату А5.




Методичні вказівки містять практичні рекомендації керування процесами та потоками в ОС Windows. Є список рекомендованої літератури.







Укладачі:

Бурчак І.Н.

^ Здолбіцький А.П.



















Рецензенти:

Сомов Д.О.



















Відповідальний за випуск:

Мельник В.А.




Затверджено науково-методичною радою ЛНТУ,

протокол № від року.







Рекомендовано до друку науково-методичною радою

НВВ інституту інженерних та інформаційних технологій ЛНТУ,

протокол № від 2009 року







Затверджено на засіданні кафедри комп’ютерної інженерії,

протокол № від року.




© Бурчак І.Н.,Здолбіцький А.П., 2009




Зміст

Керування процесами і потоками в багатозадачній операційній системі Windows з використанням функцій Win32 5

Створення процесів 5

Ідентифікація процесів 6

Вихід із процесу та його завершення 7

Очікування завершення процесу 8

Керування потоками 9

Ідентифікація потоку 10

Призупинка і продовження виконання потоку 10

Очікування завершення потоків 11

Синхронізація потоків 11

Об*єкт CRITICAL_SECTION 11

Об*єкт MUTEX 12

Об*єкт Semaphor 14

Події 15

Приклад розробки програми створення і синхронізації процесів і потоків 16

Література 23



^

Керування процесами і потоками в багатозадачній операційній системі Windows з використанням функцій Win32

Створення процесів


Функція CreateProcess – основна функція управління процесами у Win32, вона створює процес з одним потоком. Але процес вимагає наявності коду, тому у виклику функції CreateProcess необхідно вказати ім*я виконуваного файла програми. У вказану при виклику процедуру передаються два дескриптори: для процесу і для потоку. Функція CreateProcess створює новий процес з первинним потоком.


^ Синтаксис функції CreateProcess:


BOOL CreateProcess(

LPCTSTR lpApplicationName,

LPTSTR lpCommandLine,

LPSECURITY_ATTRIBUTES lpProcessAttributes,

LPSECURITY_ATTRIBUTES lpThreadAttributes,

BOOL bInheritHandles,

DWORD dwCreationFlags,

LPVOID lpEnvironment,

LPCTSTR lpCurrentDirectory,

LPSTARTUPINFO lpStartupInfo,

LPPROCESS_INFORMATION lpProcessInformation

);

Параметри:
lpApplicationName – вказує виконувану програму;

lpCommandLine – вказує параметри командного рядка;

lpProcessAttributes – вказує на структуру атрибутів безпеки процесу;

lpThreadAttributes - вказує на структуру атрибутів безпеки потоку;

bInheritHandles – визначає, чи повинен новий процес успадковувати копії відкритих успадковуваних

дескрипторів процесу, який викликав функцію;

dwCreationFlags – може об'єднувати декілька прапорів:

- СREATE_SUSPENDED – первинний потік знаходиться в стані очікування і буде запущений тільки після виклику функції ResumeThread;

- DETACHED_PROCESS і CREATE_NEW_CONSOLE – взаємовиключаючі прапори, їх неможливо установити обидва разом. Перший із них створює процес без консолі, а другий надає консоль новому процесу;

- CREATE_NEW_PROCESS_GROUP – визначає новий процес як кореневий для нової групи процесів;

lpEnvironment – вказує блок оточення для нового потоку. Блок оточення вміщує рядки імен і значень, а також шлях пошуку;

lpCurrentDirectory – визначає диск і каталог для нового процесу;

lpStartupInfo – вказує вигляд основного вікна і дескриптори стандартних пристроїв для нового процесу;

lpProcessInformation – параметр визначає структуру, в яку будуть поміщені дескриптори та ідентифікатори для створення процесу і потоку.


Структура PROCESS_INFORMATION:


typedef struct _PROCESS_INFORMATION {

HANDLE hProcess;

HANDLE hThread;

DWORD dwProcessId;

DWORD dwThreadId;

} PROCESS_INFORMATION;


^

Ідентифікація процесів



Процес може отримати ідентифікатор і дескриптор нового дочірнього процесу із структури PROCESS_INFORMATION. Для отримання опису поточного процесу використовуються функції:


HANDLE GetCurrentProcess (VOID)

DWORD GetCurrentProcessID (VOID)


Функція GetCurrentProcess насправді повертає псевдодескриптор, який не може бути успадкований. Це значення використовується, коли процесу потрібний власний дескриптор. Створити справжній дескриптор процесу можна із його ID, використовуючи у виклику функції OpenProcess значення, повернуте функцією GetCurrentProcessID:

HANDLE OpenProcess(

DWORD fdwAccess,

BOOL fInherit,

DWORD IDProcess
);

Параметри:


fdwAccess – визначає параметри доступу процесу до дескриптора. Можливі значення:

- SYNCHRONIZE – дозволяє іншим процесам чекати завершення цього процесу, використовуючи функції очікування;

- PROCESS_ALL_ACCESS – встановлені всі прапори доступу;

- PROCESS_TERMINATE – прапор робить можливим завершення процесу викликом функції TerminateProcess;

- PROCESS_QUERY_INFORMATION – прапор дозволяє використовувати дескриптор фунуціями GetExitCodeProcess i GetPrioriityClass для отримання інформації про процес;

fInherit – визначає, чи може бути новий дескриптор успадкований.

IDProcess – вміщує ідентифікатор процесу, якому потрібний дескриптор.


^

Вихід із процесу та його завершення



Після того, як процес закінчений, він викликає функцію ExitProcess з кодом завершення


VOID ExitProcess(UINT ExitCode)


Ця функція нічого не повертає; процес, який її викликав, і всі його потоки завершуються. З процесом зв*язується код завершення.

Для визначення коду завершення інший процес може використати функцію GetExitCodeProcess.


BOOL GetExitCodeProcess(

HANDLE hProcess,

LPDWORD lpExitCode

);


Процес, визначений змінною hProcess повинен мати права доступу PROCESS_QUERY_INFORMATION.

Параметр lpExitCode вказує на змінну типу DWORD, в яку буде поміщене значення. Одне з можливих значень STILL_ACTIVE, воно вказує, що процес не був завершений.

Один процес може завершити інший, якщо його дескриптор має прапор доступу PROCESS_TERMINATE. Функція, що завершує процес, також визначає код виходу із процесу:


BOOL TerminateProcess(

HANDLE hProcess,

UINT uExitCode

);

^

Очікування завершення процесу



Функції загального призначення Win32 для очікування:


DWORD WaitForSingleObject(

HANDLE hObject,

DWORD dwTimeout

);


DWORD WaitForMultipleObjects(

DWORD cObjects,

CONST HANDLE * lphObjects,

BOOL fWaitAll,

DWORD dwTimeout

);


Параметри:

lphObject – вказує на дескриптор одного процесу (типу hObject) або на масив різних об*єктів;

cObjects – розмір масиву, не повинен перевищувати константу MAXIMUM_WAIT_OBJECTS;

dwTimeout – задається в мілісекундах. Значення 0 визначає, що функція повертає результат негайно після перевірки стану об*єкта. Для нескінченного очікування завершення процесу використовуються значення INFINITE;
fWaitAll – параметр визначає (у випадку значення TRUE) необхідність очікування всіх процесів, а не тільки одного з них;

Повернуте значення: причина завершення або 0XFFFFFFFF у випадку помилки.

Можливі повернуті значення у випадку успішного завершення цієї функції:

- WAIT_OBJECT_0 - показує, що процес завершився;

- WAIT_OBJECT_0 + cObjects-1 – при очікування завершення одного із групи процесів для визначення завершеного процесу відняти із результату виконання функції константу WAIT_OBJECT_0. Якщо сигнал відіслали декілька процесів, повернуте значення буде найменшим можливим значенням змінної cObjects;

- WAIT_TIMEOUT – показує, що причиною завершення очікування буль закінчення часу очікування;

- WAIT_FAILED – показує, що виклик функції був невдалим; наприклад дескриптор не мав права SYNCHRONISE.


^

Керування потоками




Виконуваний потік в адресному просторі може бути створений системним викликом функції CreateThread, яка має синтаксис:


HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

LPDWORD lpThreadId

);

lpThreadAttributes – аналогічний структурі атрибутів безпеки;

dwStackSize – визначає розмір стека нового потоку в байтах;

lpStartAddress – вказує на функцію для виконання (в процесі, що аикликав функцію CreateThread );

lpParameter – показчик, який передається в якості параметра потоку та інтерпретується ним як показчик на структуру параметра;

dwCreationFlags - ненульове значення цього означає, що потік готовий до негайного виконання. Якщо значення цього параметра CREATE_SUSPENDED, то новий потік буде знаходитися в стані очікування до тих пір, поки не буде викликана функція ResumeThread, щоб привести його в стан готовності до виконання;

lpThreadId – вказує на змінну типу DWORD, в яку буде поміщений ідентифікатор нового потоку.

Всі потоки процесу можуть завершити своє виконання викликом функції ExitProcess, а код завершення, повернутий стартовою функцією потоку буде таким же, що і код виходу процесу.

В іншому випадку потік може завершити своє виконання викликом функції ExitThread, повернувши код завершення в функції потоку:


VOID ExitThread(DWORD dwExitCode)


При завершення процесу його стек звільнюється. Виконання процесу завершується, коли завершується його останній потік.

Потік може завершити виконання іншого потоку викликом функціїї TerminateTread, але тоді не будуть звільнені ресурси завершуваного потоку, не будуть виконані обробники завершення і не відбудеться реєстрація приєднаних динамічних бібліотек.

Завершений потік буде існувати до тих пір, поки викликом функції CloseHandle не буде закритий останній дескриптор, що посилається на нього. Код завершення цього потоку може отримати будь-який інший потік, що очікує його завершення.

Виклик функції GetExitCodeThread дозволяє отримати код завершення потоку. У випадку, коли потік ще виконується, буде отримане значення STILL_ACTIVE.

^

Ідентифікація потоку



Ідентифікатор і дескриптори потоку можуть бути отримані за допомогою функцій, аналогічних функціям для процесів:

- функція GetGurrentThread повертає неуспадковуваний псевдодескриптор викликавшого її потоку;

- функція GetGurrentThreadId отримує ідентифікатор потоку;

- функція OpenThread створює дескриптор потоку із його ідентифікатора (Windows2000);

^

Призупинка і продовження виконання потоку



Кожний потік має лічильник призупинок і може виконуватися лише при нульовому значенні цього лічильника. Потік може зменшувати або збільшувати значення лічильника призупинок іншого потоку функціями SuspendedThtread або ResumeThread:


DWORD ResumeThread(

HANDLE hThread );


DWORD SuspendedThread(

HANDLE hThread );

При успішному виконанні обидві функції повертають попереднє значення лічильника призупинок. Значення 0XFFFFFFFF повідомлює про помилку.

^

Очікування завершення потоків



Потік може очікувати завершення іншого потоку таким же чином, як потоки чекають завершення. Потрібно звернутися до функцій:

- WaitForSingleObject

- WaitForMultipleObjects,

використовуючи дескриптори потоків замість дескрипторів процесів.

^

Синхронізація потоків



В багатьох випадках виникає потреба в координації двох або більше потоків на протязі існування кожного з них. Наприклад, декілька потоків можуть здійснювати доступ до однієї і тієї ж змінної або групи змінних, що викликає взаємне виключення. в інших випадках не може продовжити роботу до тих пір, поки інший потік не дійшов до деякої точки. Два або більше потоки можуть одночасно змінювати одні і ті ж дані в глобальній пам*яті.

Win32 надає наступні об*єкти, розроблені для синхронізації потоків і процесів:

  1. критичні секції;

  2. м*ютекси;

  3. семафори;

  4. події;

  5. очікуючі таймери.



^

Об*єкт CRITICAL_SECTION



Критична секція – це частина коду, яка одночасно може виконуватися лише одним потоком; виконання такої секції одночасно більше ніж одним потоком може привести до непередбачуваних і невірних результатів.

Для реалізації ідеї критичної секції Win32 надає об*єкт CRITICAL_SECTION. Об*єкти типу CRITICAL_SECTION (КС) можуть бути ініціалізовані і видалені, але вони не мають дескрипторів і не розділяються іншими процесамми. Змінна має бути визначена як така, що має тип CRITICAL_SECTION. Потоки входять в КС і залишають її, але одночасно в КС може знаходитися лише один потік. Але потік може входити в КС і залишати її в кількох місцях програми

Для ініціалізації і видалення змінної типу CRITICAL_SECTION використовуються наступні функції:


VOID InitializeCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);


VOID DeleteCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);


Функція EnterCriticalSection блокує потік, якщо в заданій секції знаходиться інший потік. З очікуючого потоку знімається блокування, коли інший потік виконує функцію LeaveCriticalSection. Потік "володіє" КС з того моменту, коли він отримує керування від функції EnterCriticalSection, до того часу, як функція LeaveCriticalSection віддає володіння КС. Потрібно завжди віддавати володіння КС; якщо цього не зробити, інші потоки будуть змушені чекати вічно, навіть якщо володіючий потік буде завершений.


VOID EnterCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);


VOID LeaveCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);


Якщо потік вже володіє КС, він може ввійти до неї знову без блокування. Підтримується лічильник, тому потік має залишити КС стільки ж разів, скільки він ввійшов до неї, щоб звільнити КС для інших потоків.

Вихід із КС, якою даний потік не володіє, може привести до непередбачуваних наслідків, включаючи блокування.

^

Об*єкт MUTEX


Об*єкт м*ютекс надає більші можливості, ніж критичні секції коду. М*ютексу може бути присвоєне ім*я і дескриптор, тому такі об*єкти можуть бути використані для міжпроцесної синхронізації потоків в окремих процесах.

М*ютекс аналогічний об*єкту КС, але м*ютекси дозволяють використовувати тайм – аут і переходять в сигнальний стан, коли процес завершується і покидає м*ютекс.

Потік вступає у володіння м*ютексом (або блокує м*ютекс), виконуючи очікування для дескриптора м*ютекса (функція WaitForSingleObject або WaitForMultipleObjects) і звільняє його функцією ReleaseMutex.

Потоки повинні акуратно звільняти свої ресурси. Потік може отримувати певний м*ютекс декілька разів, він не буде блокувати м*ютекс, якщо вже володіє ним. В кінцевому випадку потік повинен стільки ж разів і звільнити м*ютекс.


Для роботи з м*ютексами використовуються функції Win32: CreateMutex, ReleaseMutex, OpenMutex.


HANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpMutexAttributes,

BOOL bInitialOwner,

LPCTSTR lpName

);

Значення ^ TRUE прапора bInitialOwner дозволяє викликаючому функцію потоку негайно вступити у володіння новим м*ютексом. Ця елементарна операція захищає інші потоки від захоплення володіння м*ютексом до того, як це зробить створюючий його потік. Цей прапор ігнорується, коли м*ютекс вже існує.

Прапор lpName визначає ім*я м*ютекса, яке чутливе до регістру символів. Якщо цей параметр дорівнює NULL, то м*ютекс буде безіменним. Події, м*ютекси, семафори розділяють один простір імен. Тому всі об*єкти синхронізації повинні мати різні імена, довжина імені не перевищує 260 символів. Повернуте значення NULL повідомляє про помилку.

Функція OpenMutex використовується для відкриття існуючого іменованого м*ютекса. Вона дозволяє потокам різних процесів синхронізуватися так, як будь-то вони належать до одного процесу.


HANDLE OpenMutex(

DWORD fdwAccess,

BOOL fInherit,

LPCTSTR lpszMutexName

);


Функція ReleaseMutex звільнює м*ютекс, яким володіє викликаючий потік. Якщо потік не володіє даним м*ютексом, функція не виконується.


BOOL ReleaseMutex(

HANDLE hMutex

);
^

Об*єкт Semaphor


Семафори підтримують лічильник, об*єкт-семафор переходить в сигнальний стан, коли значення цього лічильника більше нуля. При нульовому значенні лічильника об*єкт знаходиться у несигнальному стані.

Потоки або процеси виконують звичайне очікування, використовуючи одну із функцій очікування. Коли очікуючий потік звільнений, лічильник семафора зменшується на 1.

Функції для роботи з семафорами – CreateSemaphore, OpenSemaphore, ReleaseSemaphore, які можуть збільшити лічильника на 1 або на більше число. Ці функції схожі на свої аналоги для м*ютексів.


HANDLE CreateSemaphore(

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

LONG lInitialCount,

LONG lMaximumCount,

LPCTSTR lpName

);


Параметр lMaximumCount, який має бути рівним 1 або більшому числу, вказує максимальне значення для семафора.

Параметр lInitialCount, що має значення в проміжку від 0 до lMaximumCount, є початковим, і значення семафора ніколи не повинне виходити за вказані межі. Про помилки повідомляє повернуте функцією значення NULL.

Зменшити лічильника на 1 можна будь-якою функцією очікування, але звільнення семафора може збільшити його значення на будь-яке число, аж до максимуму.


BOOL ReleaseSemaphore(

HANDLE hSemaphore,

LONG cReleaseCount,

LPLONG lplPreviousCount

);

Можна визначити і попереднє значення лічильника, але якщо такої необхідності немає, показчик lplPreviousCount може мати значення NULL.

Лічильник звільнення повинен бути більше нуля, але якщо змусить семафор перевищити максимально можливе значення, то функція не виконається, поверне значення FALSE і лічильник залишиться незмінним. Звільнення семафора з більшим значенням лічильника є способом отримання поточного значення його дічильника в одній операції.

Семафор може звільнити будь-який потік, а не лише той, який виконує очікування.

Класичне використання семафорів відноситься до використання їх лічильників як представлення числа доступних ресурсів, таких як число повідомлень, що чекають в черзі. Максимум семафора відповідає максимальній довжині черги. Таким чином, виробник помістить в буфер і викличе функцію ReleaseSemaphore, зазвичай зі значенням лічильника звільнення 1. Потоки споживачів будуть виконувати очікування для семафора, отримуючи повідомлення і зменшуючи лічильник семафора.

Семафори використовуються також для обмеження числа потоків, які реально виконуються в будь-який момент, знижуючи таким чином змагання потоків за ресурси і в деяких випадках підвищуючи швидкодію.

Події


Цей об*єкт використовується для інформування інших потоків про те, що відбулася деяка подія, наприклад стало доступним деяке повідомлення.

Важлива додаткова можливість, що надається подіями, - звільнення кількох потоків від спільного очікування, коли в сигнальний стан перейшов один дескриптор. Події діляться на такі, що скидуються автоматично і вручну. Ця властивість події встановлюється при виклику функції CreateEvent:

  • подія, що скидується вручну, може сигналізувати одночасно кільком потокам, що виконують очікування події;

  • подія з автоматичним скидуванням посилають сигнали єдиному потоку, що виконує очікування.

Подіями використовуються функції CreateEvent, OpenEvent, SetEvent, ResetEvent, PulseEvent.


HANDLE CreateEvent(

LPSECURITY_ATTRIBUTES lpEventAttributes,

BOOL bManualReset,

BOOL bManualReset,

LPCTSTR lpName

);

При установленому в значення TRUE параметра bManualReset створюється подія з ручним скидуванням. Аналогічно, якщо подія повинна початково знаходитися в сигнальному стані, параметр bManualReset необхідно установити в значення TRUE.

Щоб відкрити існуючу подію, можливо, із іншого процесу, слід скористатися функцією OpenEvent .

Для керування подіями використовуються наступні три функції:


BOOL BOOL SetEvent(

HANDLE hEvent // handle to event object

);

(

HANDLE hEvent

);

BOOL ResetEvent(

HANDLE hEvent

);

BOOL PulseEvent(

HANDLE hEvent

);

Потік може перевести подію в сигнальний стан, використавши функцію SetEvent. Якщо подія скидається автоматично, єдиний (можливо із багатьох) очікуючий потік звільнюється, а подія автоматично переходить в несигнальний стан. Якщо для даної події не виконує очікування ні один з потоків, вона залишається в сигнальному стані до моменту, коли потік почне очікування, після чого він негайно звільнюється.

Якщо ж подія скидується вручну, вона залишається в сигнальному стані до тих пір, поки потік не викличе функцію ResetEvent для даної події. В цей проміжок часу всі очікуючі потоки звільнюються і можливо, що потік почне очікування і буде звільнений до скидування події.

Фунуція PulseEvent звільнює всі події, які виконують очікування для даної події з ручним скидуванням, яка потім скидується автоматично. У випадку події з автоскидуванням функція PulseEvent звільнює єдину очікуючу подію, якщо така існує.

Функція ResetEvent використовується лише після того, як подія з ручним скидуванням буде переведена в сигнальний стан функцією SetEvent.
^

Приклад розробки програми створення і синхронізації процесів і потоків


2.1.Опис базового класу CompoundSynch та похідних класів: CMutex, CCritSect, CSemaphor ( файл cls.h)

class CompoundSynch // базовий клас

{

public: //опис методiв

virtual BOOL Initialize(int) = 0;

virtual void Cleanup() = 0;

virtual void Claim(int i) = 0;

virtual void Release(int i) = 0;

};

class CMutex : public CompoundSynch //похiдний клас CMutex

{

private:

HANDLE hMutex;

public:

BOOL Initialize(int);

void Cleanup();

void Claim(int i);

void Release(int i);

};

class CCritSect : public CompoundSynch //похiдний клас CCritSect

{

private:

int iGroupNo;

HANDLE hMutex;

CRITICAL_SECTION *csShields;

public:

BOOL Initialize(int);

void Cleanup();

void Claim(int i);

void Release(int i);

};

class CSemaphor : public CompoundSynch //похiдний клас

//CSemaphor

{

private:

int iGroupNo;

HANDLE hMutex;

HANDLE *hSemaphores;

public:

BOOL Initialize(int);

void Cleanup();

void Claim(int i);

void Release(int i);

};


2.2.Опис методів класів (файл met.cpp)

#include

#include

#include "cls.h"

/*********************************************************/

/* Реалiзацiя mutex рiшення */

/********************************************************/

BOOL CMutex::Initialize(int i)

{

hMutex = CreateMutex(NULL,FALSE,NULL);

if (!hMutex) return FALSE;

return (TRUE);

};

void CMutex::Cleanup()

{

CloseHandle(hMutex);

};

void CMutex::Claim(int i)

{

WaitForSingleObject(hMutex,INFINITE);

};

void CMutex::Release(int i)

{

ReleaseMutex(hMutex);

};

/*********************************************************/

/* Реалізація рiшення критичної секцiї */

/*********************************************************/

BOOL CCritSect::Initialize(int i)

{

int iLoop;

iGroupNo = i;

csShields = (CRITICAL_SECTION *)

VirtualAlloc(0,sizeof(CRITICAL_SECTION)*i,

MEM_COMMIT,PAGE_READWRITE);

for (iLoop = 0; iLoop < i; iLoop++)

{

InitializeCriticalSection(&csShields[iLoop]);

};

return (TRUE);

};


void CCritSect::Cleanup()

{

int iLoop;

for (iLoop = 0;iLoop
DeleteCriticalSection(&csShields[iLoop]);

CloseHandle(hMutex);

VirtualFree((LPVOID)csShields,sizeof(CRITICAL_SECTION)*IgroupNo,

MEM_DECOMMIT);

};

void CCritSect::Claim(int i)

{

EnterCriticalSection(&csShields[i]);

LeaveCriticalSection(&csShields[i]);

};

void CCritSect::Release(int i)

{

EnterCriticalSection(&csShields[i]);

LeaveCriticalSection(&csShields[i]);

};

/********************************************************/

/* Реалiзацiя Semaphor рiшення */

/********************************************************/

#define SEMCOUNT 2

BOOL CSemaphor::Initialize(int i)

{

int iLoop;

iGroupNo = i;

hSemaphores = (HANDLE *)

VirtualAlloc(0,sizeof(HANDLE)*i,MEM_COMMIT,PAGE_READWRITE);

for (iLoop = 0; iLoop < i; iLoop++)

{

hSemaphores[iLoop]=CreateSemaphore(NULL,SEMCOUNT,

SEMCOUNT,NULL);

};

return(TRUE);

};

void CSemaphor::Cleanup()

{

int iLoop;

for (iLoop = 0;iLoop
{

CloseHandle(hSemaphores[iLoop]);

};

CloseHandle(hMutex);

VirtualFree((LPVOID)hSemaphores,sizeof(HANDLE)*iGroupNo,

MEM_DECOMMIT);

};

void CSemaphor::Claim(int i)

{

WaitForSingleObject(hSemaphores[i],INFINITE);

};

void CSemaphor::Release(int i)

{

ReleaseSemaphore(hSemaphores[i],1,0);

};


2.3.Головний програмний модуль ( файл tst.cpp)

#include // Для функцiї printf

#include // Для CreateThread i т.д. функцiї

#include // Прототип для rand()

#include "met.cpp" // Визначає структуру i визначення API

#include

#define GROUPS 2 // Ми тут маємо 2 групи об*єктiв ...

#define NUMBEROFTHREADS 3 // Три потоки з кожної групи

#define DELAY 50

#define DELAYBIAS 50

#define TESTLOOPS 200

class ThreadInfo

{

public:

int iID;

CompoundSynch *csSynch;

ThreadInfo(int i,CompoundSynch *csArg)

{

iID = i;

csSynch = csArg;

};

};

long WINAPI ThreadFn(ThreadInfo *lpArg)

{

int iID, iLoop, iTest;

long lWaitTime=0;

long lWaitSum=0;

long lTurnAround;

long lMaxWait=0;

long lMinWait=10000;

iID = lpArg->iID;

CompoundSynch *csSynch;

csSynch = lpArg->csSynch;

lTurnAround= timeGetTime();

for (iLoop = 0; iLoop < TESTLOOPS; iLoop++)

{

lWaitTime = timeGetTime();

// Початок критичного коду

csSynch->Claim(iID); // iдентифiкацiя

lWaitTime = timeGetTime() - lWaitTime;

lMaxWait= lMaxWait > lWaitTime ? lMaxWait : lWaitTime;

lMinWait= lMinWait < lWaitTime ? lMinWait : lWaitTime;

Sleep(DELAY-DELAYBIAS+(rand()%(2*DELAYBIAS)));

for (iTest = 0; iTest < GROUPS; iTest++)

{ if (iTest == iID) continue;

};

lWaitSum+=lWaitTime;

csSynch->Release(iID);

// Критичний код виконаний тут

Sleep(DELAY-DELAYBIAS+(rand()%(2*DELAYBIAS)));

}; //Кiнець циклу


lTurnAround= (timeGetTime() - lTurnAround)/TESTLOOPS;

printf ("Середн.час обороту для потоку iз групи %d : %8ld ms; середн.час очiкування: %lf ms, min %ld, max %ld\n\r",iID,lTurnAround,(float)lWaitSum/(float)TESTLOOPS,lMinWait,lMaxWait);

delete lpArg;

return(0);

}

void RunTestForOneObjectType(CompoundSynch *csObject,

char *szTitleOfTest)

{

HANDLE hThreads[NUMBEROFTHREADS][GROUPS];

int iLoop, iInnerLoop;

long lOldElapseTime, lNewElapseTime;

unsigned long iDummyID;

printf(szTitleOfTest);

printf("\n\r");

if (!csObject->Initialize(GROUPS)) return;

// Вибiрка часу перед початком набору програм тесту

lOldElapseTime = timeGetTime();


// Створення потокiв

for (iLoop = 0; iLoop
{

for (iInnerLoop = 0; iInnerLoop < NUMBEROFTHREADS; iInnerLoop++)

hThreads[iInnerLoop][iLoop] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFn,

(void *)new ThreadInfo(iLoop,csObject),0,&iDummyID);

};

// Початок всiх потокiв

//Зараз чекайте закiнчення

WaitForMultipleObjects(GROUPS*NUMBEROFTHREADS,(const HANDLE *)hThreads,TRUE,INFINITE);

// Вiдлiк часу, що минув

lNewElapseTime = timeGetTime();

lNewElapseTime -= lOldElapseTime;

// Очищення

for (iLoop = 0; iLoop < GROUPS; iLoop++)

for (iInnerLoop; iInnerLoop< NUMBEROFTHREADS; iInnerLoop++)

CloseHandle(hThreads[iInnerLoop][iLoop]);

printf ("Загальний минулий час: %8ld ms; на цикл: %ld ms\n\r",lNewElapseTime,lNewElapseTime/TESTLOOPS);

csObject->Cleanup();

delete csObject;

}

main()

{

RunTestForOneObjectType(new(CMutex),"Тест mutex рiшення:");

RunTestForOneObjectType(new(CCritSect),"Тест crit sect рiшення:");

RunTestForOneObjectType(new(CSemaphor),"Тест semaphor рiшення:");

return 0;

}

Література




  1. Вакал Є.С., Карпенко С.Г., Тригуб О.С. Практикум з операційних систем Windows: метод вказівки. - К., 2004.- 245с.

  2. Грайворонський М.В. Операційні системи. Лабораторний практикум. – Київ: КПІ, 2005.- 52с.

  3. Олифер В., Олифер Н. Сетевые операционные системы: Учебник для вузов, 2-е изд. – СПб: Питер, 2008. - 672с.

  4. Таненбаум Э. С. Современные операционные системы. 2-е изд. – СПб: Питер, 2007. - 1040с.

  5. Третяк В.Ф., Голубничий Д.Ю., Кавун С.В. Основи операційних систем. - Х.: Видавництво ХНЕУ, 2005. Харт, Джонсон, М. Системное программирование в среде Win32, :Пер. с англ.: - М.: Издательский дом "Вильямс" , 2001.

  6. Системное программное обеспечение./ А.В.Гордеев, А.Ю.Молчанов: - СПб.: Питер, 2001.






^ НАВЧАЛЬНО-МЕТОДИЧНЕ ВИДАННЯ


ОПЕРАЦІЙНІ СИСТЕМИ










Операційні системи. Методичні вказівки до виконання самостійної роботи студентів спеціальності КСМ денної та заочної форми навчання.




Комп’ютерний набір та верстка:

Здолбіцький А.П.







Редактор

Ю.О. Мельник










Підпис до друку . Формат 6084/16. Папір офс.

Гарн. Таймс. Ум. друк. арк. Обл.-вид.арк.

Тираж 50 прим. Зам.№




Редакційно-видавничий відділ

Луцького національного технічного університету

43018 м. Луцьк, вул. Львівська, 75.

Друк – РВВ ЛНТУ







Схожі:

Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до лабораторних занять для студентів спеціальності ксм денної та заочної форм навчання
Операційні системи. Методичні вказівки до лабораторних занять для студентів спеціальності ксм денної та заочної форми навчання. /...
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до виконання контрольної роботи для студентів спеціальності ксм заочної форми навчання
Периферійні пристрої. Методичні вказівки до виконання контрольної роботи для студентів спеціальності ксм заочної форми навчання.,...
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до лабораторних занять для студентів спеціальності ксм денної та заочної форм навчання
Операційні системи. Методичні вказівки до лабораторних занять для студентів спеціальності ксм денної та заочної форми навчання
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до лабораторних занять для студентів спеціальності «Комп’ютерні системи та мережі» денної та заочної форми навчання
Периферійні пристої. Методичні вказівки до лабораторних робіт для студентів спеціальності «Комп’ютерні системи та мережі» денної...
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до виконання лабораторних робіт з дисципліни «мова sql» для студентів денної форми навчання спеціальності
Методичні вказівки до виконання лабораторних робіт з дисципліни «Мова sql» для студентів денної форми навчання спеціальності 050....
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconКонспект лекцій для студентів спеціальності ксм
Операційні системи. Конспект лекцій для студентів спеціальності ксм денної та заочної форми навчання. / проф. Бурчак І. Н., Здолбіцький...
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до виконання економічної частини дипломних проектів, робіт для студентів денної та заочної форми навчання
Методичні рекомендації до виконання економічної частини дипломних проектів, робіт для студентів денної та заочної форми навчання...
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до виконання контрольної роботи з предмету "Вища математика" для студентів заочної форми навчання
Методичні вказівки до виконання контрольної роботи з курсу вищої математики для студентів заочної форми навчання усіх спеціальностей...
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки для самостійної роботи з курсу «Теорія І практика перекладу» для студентів 4-го курсу
Для студентів 4-го курсу денної і заочної форми навчання відділення німецької філології
Методичні вказівки до виконання самостійної роботи студентів спеціальності ксм денної та заочної форми навчання iconМетодичні вказівки до проходження навчальної практики для студентів спеціальності бдн денної форми навчання
Методичні вказівки до проходження навчальної практики для студентів спеціальності бдн денної форми навчання., Христинець Н. А. Луцьк:...
Додайте кнопку на своєму сайті:
Документи


База даних захищена авторським правом ©te.zavantag.com 2000-2017
При копіюванні матеріалу обов'язкове зазначення активного посилання відкритою для індексації.
звернутися до адміністрації
Документи