在XV6中,当调用fork()
时,子进程是以内核模式还是用户模式执行?
这是XV6中的分叉代码:
// Create a new process copying p as the parent.
// Sets up stack to return as if from system call.
// Caller must set state of returned proc to RUNNABLE.
int fork(void){
int i, pid;
struct proc *np;
struct proc *curproc = myproc();
// Allocate process.
if((np = allocproc()) == 0){
return -1;
}
// Copy process state from proc.
if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){
kfree(np->kstack);
np->kstack = 0;
np->state = UNUSED;
return -1;
}
np->sz = curproc->sz;
np->parent = curproc;
*np->tf = *curproc->tf;
// Clear %eax so that fork returns 0 in the child.
np->tf->eax = 0;
for(i = 0; i < NOFILE; i++)
if(curproc->ofile[i])
np->ofile[i] = filedup(curproc->ofile[i]);
np->cwd = idup(curproc->cwd);
safestrcpy(np->name, curproc->name, sizeof(curproc->name));
pid = np->pid;
acquire(&ptable.lock);
np->state = RUNNABLE;
release(&ptable.lock);
return pid;
}
我做了一些研究,但即使从代码中我也无法理解它是如何工作的。了解它在UNIX中的工作方式也有帮助
答案 0 :(得分:1)
除了eax
寄存器和父进程信息的值之外,它几乎是父进程的精确副本,因此它将执行父进程所处的任何上下文。
此处的fork()
函数通过调用allocproc()
创建一个新的流程结构,并使用原始流程的值填充它并映射相同的页表。
最后,它将进程状态设置为RUNNABLE
,这允许调度程序与父进程一起运行新进程。
这意味着实际运行由调度程序执行,而不是fork代码。
答案 1 :(得分:0)
塞达特所写的完全正确。分叉的进程或子进程将在与父进程相同的上下文中运行,即内核或用户。
除此之外,让alloproc()
这样的kalloc()
和诸如kstack
这样的属性使您感到困惑。这些处理针对页表和内存部分在系统中设置新过程。