#многопоточность #таймер #ос
Насколько я понимаю, процессы в компьютере выполняются не совсем параллельно, а на
самом деле быстро переключаются между собой. Но в таком случае время на завершение
всех процессов все равно остается таким же, как если бы процессы работали последовательно.
Правильно ли я понимаю, что главная фишка этой как-бы "параллельности" в том что мы
можем не дожидаться пока некий процесс закончится а перейти на другой остановив предыдущие?
Какие еще преимущества у такого принципа "параллельности"?
В таком случае, если принцип как-бы "параллельности" верен, то разве в часах на компьютере
не должно накапливаться отставание?
Ответы
Ответ 1
Ответ зависит от того, что делают ваши процессы или потоки (давайте для простоты
дальше будем говорить о потоках, которые в оригинале зовутся thread). Потоки будут
выполняться действительно одновременно, если у вас есть больше одного ядра.
Но в вопросе, как я понимаю, интересует ситуация, когда ядро одно. В этом случае
некоторые потоки все равно могут выполняться параллельно. Например, пока жесткий диск
читает данные или сетевая карта получает пакеты, то операционная система может переключиться
на другой поток, и в таких задачах будет заметен выигрыш. Если вы отправили некоторые
данные на звуковую карту, то можете пока заняться другими делами, пока она не проиграет
полученный участок звука.
Если же у вас несколько потоков, которые заняты в основном расчетами, которые занимают
ядро процессора, то в этом случае выигрыша от распараллеливания не будет, и даже будет
замедление, т.к. переключение между потоками - это не очень дешевая операция.
Ответ 2
Насколько я понимаю, процессы в компьютере выполняются не совсем параллельно, а на
самом деле быстро переключаются между собой.
В современных многозадачных операционных системах это действительно так, но в общем
случае это зависит от операционной системы.
Но в таком случае время на завершение всех процессов все равно остается таким же,
как если бы процессы работали последовательно.
Да, если вся полезная нагрузка процессов выполняется именно на процессоре. А это
далеко не всегда так. Различный ввод-вывод приводит к простою процессора. Если во время
этого простоя выполнять код другого процесса, можно сэкономить время.
Правда, это не учитывает расходы времени на т. н. context switch ("переключение контекста",
переход управления из процесса в процесс), так что чисто ЦПУшные задачи при "распараллеливании"
окажутся даже медленнее.
Правильно ли я понимаю, что главная фишка этой как-бы "параллельности" в том что
мы можем не дожидаться пока некий процесс закончится а перейти на другой остановив
предыдущие?
Да, я выше примерно это и описал :) Другие процессы могут быть и не "силой" остановлены.
Они могут остановиться сами в ожидании результата от ядра ОС.
Какие еще преимущества у такого принципа "параллельности"?
Вообще это не "параллельность" как таковая, но хорошего перевода правильного термина,
concurrency, я пока не слышал. "Конкурентность" разве что.
Concurrency имеет место, когда код структурирован не для последовательного выполнения,
а содержит определённые "разветвления" и "соединения", разные ветки которых могут (потенциально)
исполняться параллельно. Однако не обязаны. И описанный вами механизм как раз позволяет
"конкурентному" коду ужиться на одном процессоре.
Достаточно часто конкурентный код используется в рамках одного процесса (в разных
потоках [thread]), в котором поддерживается какой-то интерфейс пользователя (UI), а
из него запускается какая-то рабочая нагрузка. Они оформляются конкурентно, чтобы интерфейсом
можно было пользоваться даже когда программа занята какой-то работой.
Однако это "преимущество" строится скорее на способе определения понятия "процесс".
Скажем, в Linux различий между "процессом" и "потоком" минимум: у них всех есть собственные
"process ID", хотя снаружи их не всегда видно, т. к. перечислители процессов стараются
отдельные потоки не показывать, за ненадобностью.
Но этот же принцип встречается и в несколько неожиданной форме: интерпретаторы некоторых
языков, в частности Ruby (MRI), JS (V8) и Python (CPython), реализованы с применением
Global Interpreter Lock, и из-за этого интерпретатор в каждый момент времени может
заниматься выполнением только одного потока кода. Это существенно упрощает реализацию
интерпретатора и взаимодействующего с ним кода (расширений на С, например), хотя и
ставит дополнительные ограничения.
В таком случае, если принцип как-бы "параллельности" верен, то разве в часах на
компьютере не должно накапливаться отставание?
Да нет, там всё в порядке, поддержкой часов обычно занимается отдельное устройство
(RTC с батарейкой), а не процесс.
Иначе как бы часы шли, когда компьютер выключен? Впрочем, это легко выяснить. К примеру,
на всех моделях Raspberry Pi часы при каждом включении приходится выставлять заново.
Там реализована поддержка часов при включенном устройстве, но отдельного источника
питания для них нет. Похожим образом будет себя вести и обычный настольный компьютер,
если извлечь из материнской платы батарейку.