Окремі характеристики потоків
Ідентифікатори потоків, так само як і ідентифікатори процесів, кратні чотирьом, вибираються з того ж простору, що й ідентифікатори процесів, і з ними не перетинаються.
Як уже зазначалося, коли потік звертається до системного виклику, то перемикається в режим ядра, після чого продовжує виконуватися той же потік, але вже в режимі ядра. Тому в кожного потоку два стеки, один працює в режимі ядра, інший – у режимі користувача. Один і той самий стек не може використовуватися і в режимі користувача, і в режимі ядра. Будь-який потік може робити все що завгодно зі своїм власним стеком (стеком режиму користувача), зокрема організовувати декілька стеків і перемикатися між ними. Потік сам може визначати розмір свого стека.
При цьому не можна гарантувати, що стек матиме достатній розмір, щоб код ядра виконався без жодних проблем. Оскільки виникнення виняткової ситуації в режимі ядра може призвести до краху всієї системи, необхідно виключити таку можливість, що і здійснюється шляхом організації окремого стека для режиму ядра. Оскільки в режимі ядра можуть одночасно знаходитися декілька потоків і між ними може відбуватися перемикання, в кожного з них повинен бути окремий стек режиму ядра.
Крім стану, ідентифікатора і двох стеків, у кожного потоку є контекст, маркер доступу, а також невелика власна пам’ять для зберігання локальних змінних, наприклад для запам’ятовування коду помилки. Оскільки процес є контейнером ресурсів усіх вхідних у нього потоків, будь-який потік може дістати доступ до всіх об’єктів свого процесу, незалежно від того, яким потоком даного процесу цей об’єкт створений.
Волокна і завдання
Перемикання між потоками займає досить багато часу, тому для полегшеного псевдопаралелізму в системі підтримуються волокна (fibers). Наявність волокон дозволяє реалізувати власний механізм планування, не використовуючи вбудований механізм планування потоків на основі пріоритетів. ОС не знає про зміну волокон, для управління волокнами немає і справжніх системних викликів, проте є виклики Win32 API ConvertThreadToFiber, CreateFiber, SwitchToFiber і т.д. Докладніше функції, пов’язані з волокнами, описані у відповідній документації.
У системі є також завдання (job object), які забезпечують управління одним або кількома процесами як групою.
Внутрішня будова потоків
Перейдемо до формального опису потоків. Матеріал цього розділу однаковою мірою стосується як звичайних потоків режиму користувача, так і системних потоків режиму ядра.
Подібно до процесів, кожен потік має свій блок управління, реалізований у вигляді набору структур, головна з яких – ETHREAD – показана на рис. 3.4.
Рис. 3.4. Керуючі структури даних потоку
Зображені на рис. 3.4 структури, за винятком блоків змінних оточення потоку (TEB), існують у системному адресному просторі. Крім цього, паралельна структура для кожного потоку, створеного у Win32-процесі, підтримується процесом Csrss підсистеми Win32. У свою чергу, частина підсистеми Win32, що працює в режимі ядра (Win32k.sys), підтримує для кожного потоку структуру W32THREAD.
Блок потоку ядра KTHREAD містить інформацію, необхідну ядру для планування потоків і їх синхронізації з іншими потоками. Перегляд структур даних потоку може бути здійснений наладником. Більш детально даний матеріал викладений у відповідній літературі.
