Як працює спляча нитка?


15

Коли ви спите ниткою, що насправді відбувається?

Я бачу, що спляча нитка "призупиняє поточну нитку на заданий проміжок часу" . Але тільки як це працює?

Відповідно до того, як Thread.sleep () працює внутрішньо і як насправді працює Thread.sleep? :

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

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

Я розумію, що існує щось, що називається планувальником, який відповідає за перемикання між потоками.

Джерела, схоже, вказують на те, що це залежить від ОС (або апаратного забезпечення?), А більшості потоків надається 1 мс - 60 мс або близько того, щоб виконати деякі дії, перш ніж ЦП перейде на інший потік.

Але коли нитка спить (наприклад, багато секунд), як вона поновлюється? Я здогадуюсь, що таймер включений якось, це годинник материнської плати? Це пов'язано з тактовою частотою процесора?

І навіть якщо задіяний таймер, як процесор знає, коли настав час знову звернути увагу на нитку? Чи не доведеться постійно перевіряти потоки, щоб побачити, чи готовий він? Хіба це не ефективно опитування, а отже, це забирає час процесора?

Чи є сплячий потік, що залежить від мови, чи ОС відповідає за це чи це особливість процесора?

Хтось, будь ласка, пояснить мені це основними поясненнями таких речей, як планувальник і що ЦП робить під час всього цього?


2
Пробудження сплячої нитки знову працює за допомогою тимчасових переривань, як правило, породжених тактовою переривкою, яка є апаратним компонентом, окремим від основної частини процесора, яка обробляє інструкції. Це дозволяє уникнути потреби в опитуванні. Можливо, це пояснення щодо Quora уточнить деякі речі: quora.com/How-does-threading-work-at-CPU-level
Doc Brown

1
Більшість JVM насправді не реалізують багатопотоковість: все, що вони роблять, - це використовувати багатопотокові можливості базової операційної системи. Якщо ви дійсно хочете дізнатися, як це працює, існує багато книг на тему проектування операційної системи.
Соломон повільно

Відповіді:


11

У запуску програми значно більше, ніж просто код у цій програмі.

Будь-яка програма, яка працює в багатопроцесорній ОС, знаходиться під контролем планувальника ОС , і планувальник підтримує чітку таблицю, яка говорить про те, який процес запущений, які очікують запустити, коли цикли процесора доступні, а які навіть не є намагається бігти (спить). Планувальник, як правило, призначає процесам рівного розміру часові відрізки в залежності від їх пріоритету та історії їх виконання. У кінцевому рахунку цей цикл керується апаратними перериваннями, зазвичай генерується генератором на головній платі.

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


Це (як правило) стосується процесів, але не завжди стосується ниток, які іноді залежать від мови. Нитки можуть бути реалізовані незалежно від ОС і можуть бути спільними або попереджувальними. Наприклад, у Ruby є "волокна" (крім ниток). Рубінові волокна заплановані спільно.
david25272

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

7

Як зазначив Доктор Браун у коментарі, перерви є ключовим, і не тільки для сну.

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

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

Один фрагмент коду, керованого перериванням, який не обов'язково малий, - це планувальник. Він спрацьовує сигналом від таймера зворотного відліку та вивчає стан системи при кожному її запуску. Це, як правило, включає ідентифікацію процесів, які готові запустити (наприклад, тому, що блок, який вони чекали, прийшов у пам'ять), а також ті, які вичерпали свій часовий відрізок.

Отже, коли ви виконуєте сон нитки, то, що ви робите, - це сказати ОС, що (1) ви відмовляєтеся від свого часового відрізку, і (2) вам не слід прокидатися знову, поки не пройде певний час.

Щоразу, коли планувальник працює, він буде дивитися на ваш потік і лише позначити його як "готовий до запуску", якщо цей час минув. Це опитування, якесь своєрідне, але воно не є "зайнятим циклом" опитування, оскільки воно викликане перериванням. Це також не так вже й дорого: зазвичай одночасно працює лише тисяча або близько ниток.

Це також повинно дати вам уявлення, чому час сну не є точним: коли ваша нитка стане готова до запуску, можуть з’явитися інші потоки, які все ще запущені і не вичерпали свій часовий відрізок. Або можуть бути готові до запуску нитки з вищим пріоритетом.


Саме так працюють "сучасні" операційні системи. У старих операційних системах, таких як Windows 3 або Mac OS до OS X, процес повинен був забезпечити () управління операційною системою. На жаль, якщо програма застрягла в циклі або якось зайшла в тупик, вона ніколи не може дати контроль, і вся система зависне.
david25272

@ david25272 - Я думаю, що я використовував би слово "простіший", а не "старший", оскільки існували системи 1960-х років, які робили переважне багатозадачність. І хоча це правда, що спільне багатозадачність вимагає активного потоку зробити щось, щоб звільнити управління процесором (як правило, здійснюючи блокування виклику системи, а не явний вихід), я не вірю, що існує багато програмістів загального призначення сьогодні користуються ОС з кооперативною моделлю різьблення.
kdgregory
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.