Створення та завершення потоків у Windows, їх стани та планування.
Роботу виконав студент 46 групи Паршенков Віталій
Зміст
Планування потоків
Щоб всі потоки працювали, операційна система відводить кожному з них певний процесорний час. У Windows реалізована система багатозадачності з пріоритетами, в якій завжди виконується потік з найбільшим пріоритетом, який готовий до виконання. Вибраний для виконання потік працює протягом деякого періоду, званого квантом. Квант визначає, скільки часу виконуватиметься потік, доки операційна система не перерве його. Після закінчення кванта операційна система перевіряє, чи готовий до виконання інший потік з таким же (або більшим) рівнем пріоритету. Якщо таких потоків не виявилося, поточному потоку виділяється ще один квант. Проте потік може не повністю використовувати свій квант. Як тільки інший потік з вищим пріоритетом готовий до виконання, поточний потік витісняється, навіть якщо його квант ще не закінчився.
Квант не вимірюється в одиницях часу, а виражається цілим числом. Для кожного потоку зберігається поточне значення його кванта. Коли потоку виділяється квант процесорного часу, це означає, що його квант встановлюється в початкове значення. Воно залежить від операційної системи. Наприклад, для Win2000 Professional початкове значення кванта рівне 6, а для Win2000 Server - 36.
Це значення можна змінити викликавши Control Panel - > System -> Advanced -> Performance options. Значення «Applications» - для Win2000 Professional; «Background Services» - для Win2000 Server. Або в ключі реєстру HKLM\System\CurrentControlset\Control\PriorityControl\ Win32PrioritySeparation.
Будь-коли, коли виникає переривання від таймера, із кванта потоку віднімається 3, і так до тих пір, поки він не досягне нуля. Частота спрацьовування таймера залежить від апаратної платформи. Наприклад, для більшості однопроцесорних x86 систем він складає 10мс, а на більшості багатопроцесорних x86 систем - 15мс.
У будь-якому випадку операційна система повинна визначити, який потік виконувати наступним. Вибравши новий потік, операційна система перемикає контекст. Ця операція полягає в збереженні параметрів виконуваного потоку (регістри процесора, покажчики на стек ядра і призначений для користувача стек, покажчик на адресний простір, в якому виконується потік і ін.), і завантаженню аналогічних параметрів для іншого потоку, після чого починається виконання нового потоку.
Планування в Windows здійснюється на рівні потоків, а не процесів. Це здається зрозумілим, оскільки самі процеси не виконуються, а лише надають ресурси і контекст для виконання потоків. Тому при плануванні потоків, система не звертає уваги на те, якому процесу вони належать. Наприклад, якщо процес А має 10 готових до виконання потоків, а процес Б - два, і всі 12 потоків мають однаковий пріоритет, то кожний з потоків одержить 1/12 процесорного часу.
Прив'язка до процесорів
Якщо операційна система встановлена на комп’ютері, де встановлено більше одного процесора, то по замовчуванню, потік виконується на будь-якому доступному процесорі. Проте в деяких випадках, набір процесорів, на яких потік може працювати, може бути обмежений. Це явище називається прив'язкою до процесорів (processor affinity). Можна змінити прив'язку до процесорів програмно, через Win32-функции планування.
Пам'ять
Кожному процесу в Win32 доступний лінійний 4-гігабайтний (2^32 = 4 294 967 296) віртуальний адресний простір. Звичайно верхня половина цього простору резервується за операційною системою, а друга половина доступна процесу.
- Віртуальний адресний простір процесу доступний всім потокам цього процесу. Іншими словами, всі потоки одного процесу виконуються в єдиному адресному просторі.
- З другого боку, механізм віртуальної пам'яті дозволяє ізолювати процеси один від одного. Потоки одного процесу не можуть посилатися на адресний простір іншого процесу.
Створення потоків
- Первинний потік створюється автоматично при створенні процесу. Решта потоків створюється функціями CreateThread і CreateRemoteThread (тільки в Win NT/2000/XP).
Створений потік повинен конкретизувати адресу початку коду, який буде виконувати новий потік. Зазвичай, адреса початку коду - це ім'я функції, що визначена в коді. Ця функція бере єдиний параметр і повертає значення DWORD. Процес може мати багаторазові потоки, що одночасно виконують ту саму функцію.
- Наступний приклад демонструє, як мона створити новий потік, який виконує у визначеному місці певну функцію, MyThreadFunction.
Потік виклику використовує функцію WaitForMultipleObjects, для збереження свого стану, доки усі робочі потоки не завершаться. Запуск потоку блокується до тих пір поки функція знаходиться в стані очікування; для продовження обробки, потік виклику використовує функцію WaitForSingleObject для очікування зупинки одного з робочих потоків. Слід відзначити, що якщо знищити дескриптор для робочого потоку перед його завершенням, то цим ми не завершимо робочий потік. Проте, дескриптор буде недоступним для подальшого використання у викликах функції.
Завершення потоків
Потік завершується якщо:
- Функція потоку повертає управління.
- Потік самознищується, викликавши ExitThread.
- Інший потік даного або іншого процесу викликає TerminateThread.
- Завершується процес, що містить даний потік.
Віртуальна пам'ять може зовсім не відповідати структурі фізичної пам'яті. Диспетчер пам'яті транслює віртуальні адреси на фізичні, по яких реально зберігаються дані. Оскільки далеко не будь-який комп'ютер в змозі виділити по 4 Гбайт фізичної пам'яті на кожен процес, використовується механізм підкачки (swapping). Коли оперативної пам'яті не вистачає, операційна система переміщає частину вмісту пам'яті на диск, у файл (swap file або page file), звільняючи, таким чином, фізичну пам'ять для інших процесів. Коли потік звертається до сторінки віртуальної пам'яті, записаної на диск, диспетчер віртуальної пам'яті завантажує цю інформацію з диска назад у пам'ять.