Вопрос по c, operating-system, sleep – Как реализован режим сна на уровне ОС?

23

Мне просто интересно какsleep(time in ms) реализуется в библиотеке C или в основном на уровне ОС ...

Я предполагаю, что...

Может быть, в зависимости от скорости процессора вы делаете цикл while nop 's (я не уверен, что время сна будет точным) ...Любой специальный регистр в процессоре, где вы записываете какое-то значение, а процессор просто останавливается на указанное время (это было бы очень неэффективно, поскольку процессор может 'запускать даже другие программы).

Есть какие-нибудь подсказки? Возможно исходный код библиотеки C может объяснить? Я не слишком разборчив в том, как "С" реализует это ... Мне просто интересно, как вообще "спать()" Функция реализована.

Ваш Ответ

6   ответов
-1

загрузка процессора: 0%

требования:

create_gate (настроить обработчики IRQ)

pic_mask_clear (включить определенные прерывания)

rtc_poll (настроить RTC)

rtc_irq

smp_wake_up

; In\   RAX = Time in millisecond
; Out\  All registers preserved
sleep:
    push rcx
    push rax

    mov rcx, [rtc_irq.up_time]
    add rax, rcx
.os_delay_loop:
    hlt
    cmp qword [rtc_irq.up_time], rax
    jle .os_delay_loop

    pop rax
    pop rcx
    ret

smp_wake_up

; In\   Nothing
; Out\  Nohting
smp_wakeup_all:
    push rdi
    push rax

    mov rdi, [os_LocalAPICAddress]
    xor eax, eax
    mov [rdi+0x0310], eax   ; Write to the high bits first
    mov eax, 0x000C0080 ; Execute interrupt 0x80
    mov [rdi+0x0300], eax   ; Then write to the low bits

    pop rax
    pop rdi
    ret

rtc_irq:

; UIP (0), [email protected] (010), [email protected] (0110)
; In\   Nothing
; Out\  Nothing
rtc_irq:
    inc qword[.up_time]
    call smp_wakup_all
    ret
.up_time:       dq 0

использование :

mov rax, 1000 (millisecond)
call sleep

все в порядке

Это реализация sleep для x86_64, а не объяснение того, как sleep реализована на уровне операционной системы. JL2210
1

Ты нене делать какие-либо циклы while, иначе система победитне может ничего делать - не реагировать на мышь, клавиатуру, сеть и т. д.

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

Почему вы говорите что-то умное во второй части и в то же время так глупо в первой части? цикл while является вытесняемым и не будет нарушать любое событие мыши. v.oddou
1

Сон блокирует вашу задачу / поток за прошедшее время. Ваша задача становится недоступной для этого периода или до тех пор, пока не произойдет что-то интересное (например, сигнал), в зависимости от того, что произойдет раньше.

Нередко для режима сна вызывается метод select () и не передаются никакие дескрипторы для ожидания, а значение времени ожидания равно периоду ожидания.

Система может реализовать это, установив таймер на истечение времени после истечения времени, а затем ожидая семафора, который будет сигнализироваться по истечении этого таймера. Это блокируется на этом семафоре.

19

Sleep() реализован на уровне ОС. Процессор не 'вращаться, когда задача / поток / процесс спит. Этот конкретный поток помещается в очередь ожидания (поток неt готов к запуску), пока не истечет время, в которое поток будет помещен в очередь готовности к запуску.

Тем временем будут запущены другие готовые к запуску потоки.

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

Только для очень простой системы (например, самой простой из встроенных систем)Sleep() на самом деле быть реализован как не более чем занятой цикл ожидания.

Любой учебник по операционной системе, например "Современные операционные системы » Таненбаум расскажу об этом очень подробно - почти любой из них (даже старый, дешевый, использованный).

@ v.oddou Можете ли вы рассказать о тикающих операциях против тиковых? Я чувствую, что это фундаментальное объяснение того, как на самом деле реализуется сон. CMCDragonkai
Довольно убедительная куча тестов для FreeBSD сделана в этой теме. мы видим, что при низком разрешении HZ функции сна ведут себя плохо.lists.freebsd.org/pipermail/freebsd-java/2015-November/... v.oddou
аааа .. так что не гарантируется, что он проснется после истечения времени ожидания .. Это до планировщика или в основном других задач в системе ... ?? FatDaemon
Гарантируется, что НЕ будет работать, пока таймер не работает. Quinn Wilson
2

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

Безусловно, и следует отметить, что процесс Idle является процессом, который выполняет инструкцию HLT. В современных процессорах он становится очень сложным, и в зависимости от периода ожидания он переключается в режимы CN. (C0 бодрствует, C1 короткий сон, ... C7 длинный сон) v.oddou
2

Ответ на ваш вопрос полностью зависит от операционной системы и реализации.

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

Похожие вопросы