Реалізація потоків в ядрі Linux

Нить – це популярна сьогодні програмна абстракція Вона забезпечує виконання декількох потоків в спільно використовуваному адресному просторі памяті Потоки також можуть спільно використовувати відкриті файли та інші ресурси Нить використовується дляпаралельного програмування (concurrent programming), Що на багатопроцесорних системах забезпечує істинний паралелізм

Реалізація потоків в операційній системі Linux унікальна Для ядра Linux не існує окремоїконцепціїпотоків У ядрі Linux потоки реалізовані так само, як і звичайні процеси В ОС Linux немає ніякої особливої ​​семантики для планування виконання потоків або яких-небудь особливих структур даних для представлення потоків Поток-це просто процес, який використовує деякі ресурси спільно з іншими процесами Кожен потік має структуру task_struc t і представляється для ядра звичайним процесом (який спільно використовує ресурси, такі як адресний простір, з іншими процесами)

У цьому сенсі Linux відрізняється від інших операційних систем, таких як Microsoft Windows або Sun Solaris, які маютьявнізасоби підтримки потоків в ядрі (у цих системах іноді потоки називаються процесами з швидким перемиканням контексту, lightweight process) Назва процес з швидким перемиканням контексту показує різницю між філософією Linux та інших операційних систем Для інших операційних систем потоки-це абстракція, яка забезпечує полегшені, більш швидкі для виконання сутності, ніж звичайні важкі процеси Для операційної системи Linux потоки – це просто спосіб спільного використання ресурсів декількома процесами (які й так мають достатньо малий час перемикання контексту) 11

Припустимо, у нас є процес, що складається з чотирьох потоків В операційних системах з явною підтримкою потоків повинен існувати дескриптор процесу, який далі вказує на чотири потоку Дескриптор процесу описує спільно використовувані ресурси, такі як адресний простір і відкриті файли Потоки описуються ресурсами, які належать тільки їм В ОС Linux, навпаки, існує просто чотири процесу і, відповідно, чотири звичайні структури task_struct Чотири процесу побудовані так, щоб спільно використовувати певні ресурси

Потоки створюються так само, як і звичайні завдання, за винятком того, що в системний виклик clon e () передаються прапори із зазначенням, які ресурси мають використовуватися спільно:

Clone (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0)

11Как примі р можна привести тести з измерени ю часу створення процесів (і навіть потоків) і операційно й системі Linux порівняно ю з іншими операційним і системами Результати дуже хороші

Результат виконання показаного коду буде таким же, як і при виконанні звичайного виклику for k (), за винятком того, що адресний простір, ресурси файлової системи, дескриптори файлів і обробники сигналів залишаться загальними Іншими словами, нова задача, так само як і батьківський процес, – звичайні потоки На відміну від цього, звичайний виклик for k () може бути реалізований наступним чином:

clone (SIGCHLD, 0)

а виклик vfor k () у такому вигляді:

clone (CLONE_VFORK | CLONE_VM | SIGCHLD,  0)

Прапори, що передаються до системний виклик clon e (), допомагають вказати особливості поведінки нового процесу і деталізувати, які ресурси повинні бути загальними для батьківського і породженого процесів У табл 31 наведені прапори системного виклику clon e () і їх ефект

Таблиця 31 Прапори системного виклику clon e ()

Прапор Опис

CLONE_FILES CLONE_FS CLONE_IDLETASK

CLONE_NEWNS

CLONE_PARENT

CLONE_PTRACE CLONE_SETTID CLONE_SETTLS

CLONE_SIGHAND CLONE_SYSVSEM CLONE_THREAD CLONE_VFOK

CLONE_ONTRACED

CLONE_3T0P CLONE_CHILD_CLEARTID CLONE_CHILD_SETTID CLONE_PARENT_SETTID CLONE_VM

Батьківський і породжений процеси спільно використовують відкриті файли

Батьківський і породжений процеси спільно використовують інформацію про файлову систему

Встановити значення PID в нуль (використовується тільки для неодружених

(Idle) задач)

Створити новий простір імен для породженої завдання

Батьківський процес викликає процесу стає батьківським і для породженого

Продовжити трасування і для породженого процесу

Повернути значення ідентифікатора TID в простір пользовател Для породженого процесу створити нову область локальних дан-

вих потоку (thread local storage, TLS)

У породженого і батьківського процесів будуть спільні обробники сигналів

У батьківського та породженого процесів буде загальна семантика обробки прапора SEM_UNDO ДЛЯ семафорів System V

Батьківський і породжений процеси будуть належати одній групі потоків

Використовувати vf or k (): Батьківський процес буде перебувати

а припиненому стані, поки породжений процес не відновить його роботу

Заборонити батьківському процесу використання прапора

CLONE_PTRAC E для породженого процесу

Запустити процес в стані TASK_STOPPE D

Очистити ідентифікатор TID для породженого процесу Встановити ідентифікатор TID для породженого процесу Встановити ідентифікатор TID для батьківського процесу

У породженого і батьківського процесів буде загальний адресний простір

Потоки в просторі ядра

Часто в ядрі корисно виконати деякі операції у фоновому режимі У ядрі така можливість реалізована за допомогою потоків простору ядра (kernel thread) – звичайних процесів, які виконуються виключно в просторі ядра Найбільш істотною відмінністю між потоками простору ядра і звичайними процесами є те, що потоки в просторі ядра не мають адресного простору (значення покажчика mm для них одно NULL) Ці потоки працюють тільки в просторі ядра, і їх контекст не переходить в простір користувача Тим Проте потоки в просторі ядра плануються і витісняються так само, як і звичайні процеси

У ядрі Linux потоки простору ядра виконують певні завдання, найбільш часто використовувані, – цеpdflush  іksoftirq Ці потоки створюються при завантаженні системи іншими потоками простору ядра Насправді потік в просторі ядра може бути створений тільки іншим потоком, працюючим в просторі ядра Інтерфейс для запуску нового потоку в просторі ядра з вже існуючого потоку наступний:

int kernel_thread(int (*fn) (void *) , void * arg, unsigned long flags)

Нова задача створюється за допомогою звичайного системного виклику clon e () з відповідними значеннями прапорів, зазначеними в параметрі flags При поверненні з системного виклику батьківський потік режиму ядра завершується і повертає покажчик на структуру task_struc t породженого процесу Породжений процес виконує функцію, адреса якої вказана в параметрі fn, як аргумент цієї функції передається параметр arg Для вказівки звичайних прапорів потоків простору ядра існує прапор CLONE_KERNEL, який обєднує в собі прапори CLONE_FS, CLONE_FILES і CLONE_SIGHAND, так як більшість потоків простору ядра повинні вказувати ці прапори в параметрі flags

Найчастіше потік простору ядра продовжує виконувати свою функцію вічно (або, принаймні, до перевантаження системи, але коли вона відбудеться у випадку ОС Linux невідомо) Функція потоку зазвичай містить замкнутий цикл, в якому потік простору ядра по необхідності відновлює виконання, виконує свої обовязки і знову переходить в призупинене стан

У наступних розділах більш детально будуть розглянуті конкретні приклади потоків простору ядра

Джерело: Лав, Роберт Розробка ядра Linux, 2-е видання : Пер з англ – М: ТОВ «ІД Вільямс »2006 – 448 с : Ил – Парал тит англ

Схожі статті:


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

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*