struct {
struct spinlock lock;
struct proc proc[NPROC];
} ptable;
位于proc.c文件中。
有人可以解释一下它的初始化位置吗? 因为,在proc.c中我从来没有看到某些东西(进程)被添加到它。
更确切地说,让我们说我正在查看调度程序代码:
void
scheduler(void)
{
struct proc *p;
for(;;){
// Enable interrupts on this processor.
sti();
// Loop over process table looking for process to run.
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p−>state != RUNNABLE)
continue;
// Switch to chosen process. It is the process’s job
// to release ptable.lock and then reacquire it
// before jumping back to us.
proc = p;
switchuvm(p);
p−>state = RUNNING;
swtch(&cpu−>scheduler, proc−>context);
switchkvm();
// Process is done running for now.
// It should have changed its p−>state before coming back.
proc = 0;
}
release(&ptable.lock);
}
}
在:
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
你可以看到我们正在循环遍历ptable中的每个进程。我的问题是,他们是如何到达那里的? 谢谢!
答案 0 :(得分:3)
初始化。
struct {
struct spinlock lock;
struct proc proc[NPROC];
} ptable;
上面的代码定义了一个struct(没有名称),并将ptable
初始化为此类型的一个结构。
也许你对这种语法感到困惑:
struct ptable {
struct spinlock lock;
struct proc proc[NPROC];
};
这里我们只定义一个结构名称ptable
,并且没有初始化。
答案 1 :(得分:2)
您将无法在xv6的代码中找到初始化。这就是原因。
C将proc的int和enum变量初始化为0.当实现ptable
时,struct proc proc[NPROC];
创建一个包含64个进程的数组,其字段由语言初始化为0。 0恰好是UNUSED枚举的值。
allocproc通过ptable.proc循环查找state = UNUSED,然后将找到的第一个初始化为所有需要的值。因此,无需显式初始化数组中的结构。
答案 2 :(得分:1)
struct {
struct spinlock lock;
struct proc proc[NPROC];
}ptable;
它被分配在堆栈上并自动初始化。这里的技巧是它以GCC方式编写,也称为匿名结构。
答案 3 :(得分:0)
作为全局变量的结构体 ptable
在 xv6 内核启动期间作为 bootmain()
调用的一部分加载到内存中。因为它是全局的,所以默认值被初始化。
现在来看看它们如何实际用于存储过程以及何时修改条目。
userinit()
创建,它选择一个未使用的条目并将其用于设置自己的 PCB。fork()
以生成一个 shell,该 shell 在每次调用时调用 allocproc()
从 ptable 获取另一个未使用的条目并将其分配给进程。这是在 fork 期间填充 ptable 的方式,并帮助 xv6 记录活动进程。