Как работает сон нить?


14

Когда вы спите нить, что на самом деле происходит?

Я вижу, что спящий поток «приостанавливает текущий поток на определенный период времени» . Но как это работает?

В соответствии с тем, как Thread.sleep () работает внутри и как Thread.sleep действительно работает? :

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

Я просто не могу понять внутреннюю и фундаментальную механику того, что все это значит.

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

Похоже, источники указывают, что это зависит от ОС (или оборудования?), И большинству потоков отводится 1 - 60 мс или около того, чтобы выполнить некоторые действия, прежде чем ЦП переключится на другой поток.

Но когда поток спит (например, много секунд), как он возобновляется? Я предполагаю, что таймер как-то задействован, часы материнской платы? Это связано с тактовой частотой процессора?

И даже если задействован таймер, как процессор узнает, когда пришло время снова обратить внимание на поток? Не нужно ли постоянно проверять ветку, чтобы увидеть, готова ли она? Разве это не эффективно опрос и поэтому вид будет потреблять процессорное время?

Спит ли поток в зависимости от языка, или ОС отвечает за него, или это зависит от процессора?

Может, кто-нибудь объяснит мне основные объяснения таких вещей, как планировщик и то, что процессор делает во время всего этого?


2
Пробуждение спящего потока снова работает по временным прерываниям, обычно генерируемым часами прерываний, которые являются аппаратным компонентом, отдельным от основной части ЦП, которая обрабатывает инструкции. Это позволяет избежать необходимости опроса. Возможно, это объяснение Quora прояснит некоторые вещи: quora.com/How-does-threading-work-at-CPU-level
Док Браун

1
Большинство JVM на самом деле не реализуют многопоточность: все, что они делают, - это используют возможности многопоточности базовой операционной системы. Если вы действительно хотите знать, как это работает, есть много книг на тему дизайна операционной системы.
Соломон Медленный

Ответы:


11

Запуск программы намного больше, чем просто код в этой программе.

Любая программа, работающая в многопроцессорной ОС, находится под контролем планировщика ОС , и планировщик поддерживает явную таблицу, в которой указано, какой процесс выполняется, какие из них ожидают запуска, когда доступны циклы ЦП, а какие нет. пытаюсь бежать (спит). Планировщик обычно присваивает процессам временные интервалы одинакового размера в зависимости от их приоритета и истории выполнения. В конечном счете, этот цикл управляется аппаратными прерываниями, обычно генерируемыми генератором на основной плате.

Спящий всегда является функцией, которую язык программирования может поддерживать только потому, что среда выполнения, в которой он будет выполняться, поддерживает его. Обычная программа не может приостановить саму себя , она может только сказать планировщику, как она хотела бы, чтобы ее обрабатывали - и планировщик никоим образом не обязан или даже не всегда способен удовлетворить это желание. Подумайте о том, что ноутбук закрыт и входит в спящий режим; генератор основной платы продолжает пульсировать, но, поскольку планировщик не работает, ни один процесс не может быть запущен, независимо от того, насколько высок его приоритет.


Это (обычно) верно для процессов, но не всегда верно для потоков, которые иногда зависят от языка. Потоки могут быть реализованы независимо от ОС и могут быть кооперативными или вытесняющими. Например, в Ruby есть «волокна» (в дополнение к нитям). Рубиновые волокна запланированы совместно.
david25272

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

7

Как отметил в комментарии Док Браун , прерывания - это ключ, и не только для сна.

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

Код обработки прерываний, как правило, очень маленький и очень быстрый. Например, когда диск указывает, что блок был скопирован в память, ОС может просто записать этот факт в список «готовых блоков» где-нибудь и затем вернуться к тому, что еще делала. Вы не хотите, чтобы центральный процессор проводил все свое время в коде обработки прерываний и не выполнял пользовательский код.

Планировщиком является не обязательно маленький код, управляемый прерываниями . Он запускается сигналом таймера обратного отсчета и проверяет состояние системы при каждом запуске. Обычно это включает в себя определение процессов, которые готовы к запуску (например, потому что блок, который они ожидали, поступил в память), а также тех, которые исчерпали свой временной интервал.

Таким образом, когда вы выполняете спящий поток, вы сообщаете ОС, что (1) вы отказываетесь от своего временного интервала, и (2) вы не должны просыпаться снова, пока не истечет определенное время.

Всякий раз, когда планировщик запускается, он просматривает ваш поток и помечает его как «готовый к запуску» только по истечении этого времени. Это опрос, в некотором роде, но это не опрос "занятой петли", поскольку он запускается прерыванием. Это также не так уж и дорого: обычно за один раз выполняется только около тысячи потоков.

Это также должно дать вам представление о том, почему время ожидания не является точным: когда ваш поток готов к работе, могут быть другие потоки, которые все еще работают и не исчерпали свой временной интервал. Или могут быть потоки с более высоким приоритетом, которые готовы к запуску.


Так работают «современные» операционные системы. В более старых операционных системах, таких как Windows 3 или Mac OS до OS X, процесс должен был предоставить () контроль операционной системе. К сожалению, если программа застрянет в цикле или каким-либо образом заблокируется, она может никогда не дать управление, и вся система зависнет.
david25272

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