我只是对{C}库中实现sleep(time in ms)
或基本上在操作系统级别实现的感兴趣......
我在猜...
任何线索?可能C库的源代码可以解释一下吗?我并不太关注“C”是如何实现的......我只是想知道“sleep()”函数是如何实现的。
答案 0 :(得分:19)
Sleep()
在操作系统级别实施。当任务/线程/进程正在休眠时,处理器不会旋转。该特定线程被置于挂起队列(线程尚未准备好运行),直到时间到期,此时线程将被置于准备运行队列中。
与此同时,将运行准备运行的其他线程。
只有当没有线程准备好运行时,操作系统才会进入空闲线程,这通常会发出关闭处理器(或者无论如何都处于低功耗状态)的指令,直到发生硬件中断为止。
仅对于一个非常简单的系统(如最简单的嵌入式系统),Sleep()
实际上可以实现为繁忙的等待循环。
任何操作系统教科书,例如"Modern Operating Systems" by Tanenbaum都将非常详细地介绍它 - 几乎任何一本教科书(即使是旧的,便宜的,用过的)。
答案 1 :(得分:2)
您的问题的答案完全取决于操作系统和实现。
一种考虑它的简单方法:当您调用sleep()
时,操作系统会计算唤醒时间,然后将您的进程粘贴到某个优先级队列中。然后它只是不安排你的进程获得任何执行时间,直到足够的真实的时间已经从队列中弹出。
答案 2 :(得分:2)
在典型的操作系统中,睡眠调用内核,它将进程设置为等待指定的时间量过去,然后继续查找要运行的其他进程。没有更好的事情,它将运行'空闲过程'。一旦时间流逝,调度程序将注意到睡眠过程是好的,它将再次安排它。
答案 3 :(得分:1)
你不做任何循环,否则系统将无法做任何事情 - 不响应鼠标,键盘,网络等。
通常大多数操作系统都会将延迟添加到当前时间戳,以便在恢复请求延迟的任务时获取时间戳(假设此时没有运行更高优先级的任务)并添加[wakeupTimestamp] ,任务指针]到按时间戳升序排序的列表。之后,OS执行上下文切换并运行下一个可用任务。系统会定期将困眠列表中最早的时间戳与当前时间戳进行比较,如果截止日期已过,则会将休眠任务移动到“就绪”任务队列中。
答案 4 :(得分:1)
Sleep会阻止你的任务/线程传递时间值。你的任务在那段时间内变得无法运行,或直到其他有趣的事情发生(如信号),以较早者为准。
睡眠调用select()并且不传递任何描述符等待并且超时值等于您的睡眠时间并不罕见。
系统可以通过将计时器设置为在经过一段时间后到期,然后等待在该计时器到期时将发出信号的信号量来实现此目的。因此它被阻塞在那个信号量上。
答案 5 :(得分:-1)
cpu用法: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), RTC@32.768KHz (010), Rate@1024Hz (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
很好