Вопрос

Просто любопытно.Как на самом деле работает функция Sleep() (объявленная в windows.h)?Может быть, не только эта реализация, но и любой другой.Под этим я подразумеваю - как это реализовано?Как это может заставить код "остановиться" на определенное время?Также любопытно, как cin >> и те, кто на самом деле работа.Что именно они делают?

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

Это было полезно?

Решение

Операционная система использует механизм, называемый планировщиком, чтобы все потоки или процессы, которыми она управляет, вели себя нормально вместе.

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

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

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

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

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

Если требуется большая точность или очень короткое ожидание, единственный вариант - использовать упомянутую вами конструкцию цикла занятости.

Другие советы

Операционная система планирует, как выполняются процессы (какие процессы могут выполняться, в каком порядке, ...).Sleep() вероятно, выдает системный вызов, который сообщает ядру “не разрешайте мне использовать процессор для x миллисекунды”.

Короче говоря, Sleep() сообщает операционной системе некоторое время игнорировать процесс / поток.

"cin" использует тонну перегруженных операторов.'>>', который обычно имеет битовый сдвиг вправо, перегружен практически для каждого типа правостороннего операнда в C ++.Для каждого из них предусмотрена отдельная функция, которая считывает данные с консоли и преобразует входные данные в тот тип переменной, который вы указали.Например:

std::cin::operator>> (int &rhs);

Это не настоящий C ++ — я давно не работал с потоками и перегрузкой, поэтому не помню возвращаемый тип или точный порядок аргументов.Тем не менее, эта функция вызывается, когда вы запускаете cin >> целочисленную переменную.

Точная базовая реализация зависит от операционной системы.

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

Если вы ищете более контролируемый способ блокировки потока / процесса в многопоточной программе, взгляните на семафоры, мьютексы, критические разделы и события.Все эти методы используются для блокировки процесса или потока (без загрузки процессора с помощью конструкции while).

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

На низком уровне в системе есть процедура, называемая "планировщик", которая отправляет инструкции от всех запущенных программ центральному процессору (ЦП), который фактически их запускает.Системные вызовы, такие как "Sleep" и "usleep", соответствуют инструкциям, которые предписывают планировщику ИГНОРИРОВАТЬ этот поток или процесс в течение фиксированного промежутка времени.

Что касается потоков C ++, "cin" скрывает фактический дескриптор файла (stdin и stdout на самом деле являются такими дескрипторами), к которому вы обращаетесь, а оператор ">>" для него скрывает базовые вызовы для чтения и записи.Поскольку это интерфейс, реализация может зависеть от операционной системы, но концептуально он по-прежнему выполняет такие вещи, как printf и scanf под капотом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top