进程刚开始创建的时候,会放再哪个队列,runqueue还是waitqueue
时间: 2024-04-04 19:31:17 浏览: 136
当进程刚开始创建时,它会被加入到当前 CPU 的可执行队列(runqueue)中,处于 `TASK_RUNNING` 状态,以等待 CPU 时间片调度并运行。只有在进程需要等待某个事件(如 I/O 完成)时,才会将它加入到相应的等待队列(waitqueue)中,此时进程状态会被设置为 `TASK_INTERRUPTIBLE` 或 `TASK_UNINTERRUPTIBLE`,并且进程不再处于可执行状态,直到等待的事件发生并将进程从等待队列中唤醒。因此,进程刚开始创建时会放在可执行队列中,而不是等待队列中。
相关问题
sched_core_fork 会把子进程放入到runqueue吗
sched_core_fork 函数并不会直接将子进程放入到运行队列中。相反,它会将子进程的调度实体加入到调度器的任务队列中,等待被调度执行。
具体来说,当一个进程调用 fork 函数时,内核会创建一个新的进程作为它的子进程。在创建子进程时,内核需要为子进程创建一个新的调度实体,以便调度器可以对其进行调度。sched_core_fork 函数就是用于创建新的调度实体的。
sched_core_fork 函数会在创建子进程的过程中,将其调度实体加入到调度器的任务队列中,等待被调度执行。当子进程被调度执行时,调度器会将其调度实体从任务队列中取出,并将其加入到对应的运行队列中,等待被 CPU 执行。
需要注意的是,调度器会为每个 CPU 分配一个独立的运行队列,并且每个运行队列都被保护在一个自旋锁中,因此当需要访问运行队列时,需要首先获取对应的自旋锁,以避免并发访问导致的问题。
runqueue是在什么时候创建的
`runqueue` 不是在某个特定时刻创建的,而是在调度器初始化时被创建的。在 Linux 内核中,调度器是在内核启动时初始化的。具体来说,在 `start_kernel()` 函数中会调用 `sched_init()` 函数对调度器进行初始化。在 `sched_init()` 函数中,会调用各个调度器的初始化函数,如 `sched_init_granularity()`、`sched_init_numa()`、`sched_init_cpu()`、`init_dl_task_timer()` 等等,这些函数会初始化调度器中各个子系统的数据结构。其中,就包括 `runqueue` 数据结构。在 O(1) 调度器中,`runqueue` 被定义为一个全局变量,并在 `sched_init()` 函数中初始化。在 CFS 调度器中,`runqueue` 被定义为一个红黑树,并在 `sched_init()` 函数中初始化。
在调度器初始化完毕后,`runqueue` 就可以用于存储就绪进程队列了。当新的进程被创建时,会将其插入到适当的 `runqueue` 中。当 CPU 空闲时,调度器会从 `runqueue` 中选择一个进程来运行。因此,`runqueue` 是调度器的一个重要数据结构,它在调度器初始化时被创建,并在进程调度过程中被使用。
阅读全文