Особливості багатозадачності в середовищі Windows

Контрольная работа - Компьютеры, программирование

Другие контрольные работы по предмету Компьютеры, программирование

?зділі.

for(int i = 0;i<1000;i++)

{

mas[i] = i;

}

// Вихід із захищеного розділу:

// звільняємо обєкт для доступу

// до захищеного розділу інших задач.

ReleaseMutex(CritMutex);

}

return 0;

}

// Другий потік: зчитування даних з масиву.

DWORD thread2(LPVOID par)

{ // Зчитування значень з масиву.

int j;

// Запит на вхід у захищений розділ.

DWORD dw = WaitForSingleObject(CritMutex,INFINITE);

if(dw == WAIT_OBJECT_0)

{ // Якщо обєкт звільнений коректно, те

// виконання коду в захищеному розділі.

for(int i = 0;i<1000;i++)

{

j = mas[i];

}

// Вихід із захищеного розділу:

// звільняємо обєкт для доступу

// до захищеного розділу інших задач.

ReleaseMutex(CritMutex);

}

return 0;

}

Лістинг 3. Зняття графічного потоку

void breakTask(GF_Task* tsk)

{

DWORD result;

char s[512];

// Команда задачі, що знімається, на зняття.

tsk->putState(tsBreak,True);

// Чекаємо завершення потоку протягом 1 с.

WaitForSingleObject(tsk->TaskHnd95,1000);

//

// Аналіз відповіді.

//

if(result == WAIT_OBJECT_0) // Ok - потік довершений успішно.

{

result = cmOK;

goto _L_EndbreakTask;

}

else if(result == WAIT_TIMEOUT) // Потік не відповідає.

{ // Підготовляємо рядок запиту.

sprintf(s,,

"Потік # %і не відповідає...\nобїект %s\n Зробіть вибір: \n\

Так - повторити команду на зняття \n\

Немає - зняти потік примусово \n\

Скасувати - не знімати потік"

TaskCollection->indexOf(tsk)+1,

tsk->getName());

}

// Висновок запиту на екран.

result = MsgBox(s, msg|msgSound);

switch(result) // Аналіз відповіді.

{

case cmNo: // Примусове зняття потоку.

tsk->putState(tsCrash,True); // Виставляємо прапор

tsk->endTask(); // Заключні операції

TerminateThread(tsk->TaskHnd95,0); // Знімаємо потік

goto _L_EndbreakTask;

case cmCancel: // Скасування зняття потоку.

goto _L_EndbreakTask;

}

}

else if(WAIT_FAILED) // Відбулася помилка доступу до обєкта.

{ // Примусове зняття потоку.

SIL(); // Звуковий сигнал

tsk->endTask(); // Заключні операції

TerminateThread(tsk->TaskHnd95,0);

SIL(); // Звуковий сигнал

result = cmNo;

goto _L_EndbreakTask;

}

}

_L_EndbreakTask:

CloseHandle(tsk->TaskHnd95);

tsk->TaskHnd95 = 0;

tsk->putState(tsWorkTask,False); // Знімаємо прапори

return result;

}

// Код потоку, що знімається, приблизно наступний:

DWORD thread1(LPVOID par)

{

while((state & tsBreak) == 0)

{ // Поки прапор tsBreak не виставлений, виконуємо потік.

draw() // Щось виводимо на екран.

}

return 0;

}

 

Завдання на виконання

 

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

Написати з використанням подій програму, що реалізують таку схему за допомогою подій. Нехай є клієнт та сервер, які повинні спілкуватись між собою. Спочатку сервер (це один потік) просто чекає. Клієнт (другий потік) приймає у користувача повідомлення та передає його серверу. Сервер обробляє повідомлення, а саме: він формує нове повідомлення яке складається з n повторів початкового повідомлення, де n кількість символів у початковому повідомленні. Весь цей час клієнт чекає, потім отримує відповідь і виводить її користувачу.

Виконати завдання №1 використовуючи механізм таймерів. (треба виставити достатній час для обробки запитів.)

Написати програму, що має два потока; один готує дані (наприклад зчитує з файла), а інший відсилає їх на сервер. Треба розпаралелити їх роботу. Тут потоки повинні працювати по черзі. Спочатку перший потік готує порцію даних. Потім другий потік відправляє її, а перший тим часом готує наступну порцію і т.д. (для такої синхронізації потрібно буде дві події “автосбросом”).

Написати з використанням мютекса програму, що створює десять процесів, кожен з яких у свою чергу створює десять потоків, у кожному з потоків треба підрахувати значення факторіалу сумі свого номеру (a) та номеру свого процесу (b), потім занести номер свого процесу (1-10), свій номер (1-10), та обчислене значення у файл (вхід у стек). Після цього кожен потік повинен обчислити значення ступеню a^b. Знову, аналогічним чином відмітитись у файлі та, якщо можна, залишити відмітку про вихід зі стеку. Якщо вийти зі стеку неможливо чекати і потім вийти. Таким чином кожен потік пише у файл два рази або один раз. Переконатись у тому, що є потоки, які не чекають своєї черги вийти зі стеку. (Стек повинен спрацювати за стандартним правилом: перший зайшов останній вийшов.)

Виконати завдання №4 використовуючи механізм подій (детально продумайте схему, прийдеться використовувати досить багато подій).

Виконати завдання №4 використовуючи критичні секції.

Виконати завдання №4 використовуючи семафор.

Виконати завдання №4 з тією різницею, що потоки повинні створити чергу. (Черга працює за правилом FIFO. Перший зайшов перший вийшов. Поки не вийдуть всі потоки перед данним, він повинен чекати).

Виконати завдання №5 з тією різницею, що потоки повинні створити чергу. (Черга працює за правилом FIFO. Перший зайшов перший вийшов. Поки не вийдуть всі потоки перед данним, він повинен чекати).

Виконати завдання №6 з тією різницею, що потоки повинні створити чергу. (Черга працює за правилом FIFO. Перший зайшов перший вийшов. Поки не вийдуть всі потоки перед данним, він повинен чекати).

Виконати завдання №7 з тією різницею, що потоки повинні