```Java
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ็ถ่ฟ็จ (ๅจ็จๆทๆ) ่ฐ็จ fork() โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| (่งฆๅ็ณป็ป่ฐ็จ๏ผ่ฟๅ
ฅๅ
ๆ ธ)
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ (็ถ่ฟ็จๅ
ๆ ธๆ) ๆง่ก fork(): โ
โ โ
โ 1) p = myproc(); // ๆฟๅฐๅฝๅ(็ถ)่ฟ็จ p โ
โ 2) np = allocproc(); // ๅ้
ๅนถๅๅงๅๅญ่ฟ็จ np โ
โ 3) uvmcopy(...); // ๆท่ด็ถ่ฟ็จๅ
ๅญ็ปๅญ่ฟ็จ โ
โ 4) np->trapframe->a0 = 0; // "ๅญ่ฟ็จ"็่ฟๅๅผๅฏๅญๅจ่ฎพไธบ 0 โ
โ 5) for(i=0..NOFILE) filedup(...) // ๅคๅถๆไปถๆ่ฟฐ็ฌฆ็ปๅญ่ฟ็จ โ
โ np->cwd = idup(p->cwd); // ๅคๅถๅทฅไฝ็ฎๅฝ โ
โ safestrcpy(np->name, p->name); // ๅญ่ฟ็จ็ปงๆฟๅๅญ โ
โ 6) pid = np->pid; // ่ฎฐๅฝๅญ่ฟ็จ็PID โ
โ 7) np->state = RUNNABLE; // ๅญ่ฟ็จ็ฝฎไธบๅฐฑ็ปช โ
โ 8) return pid; // ๅ
ๆ ธๆ่ฟๅ pid โ ็ถ่ฟ็จ็จๆทๆ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| (ๅๆขๅ็ถ่ฟ็จ็จๆทๆ)
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ็ถ่ฟ็จ็จๆทๆๅพๅฐ fork() == pid โ
โ (็ถ่ฟ็จ็ปง็ปญๆง่ก่ชๅทฑ็ๅ็ปญไปฃ็ ) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---- (ๅๅฒ็บฟ) ----
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๅญ่ฟ็จๆญคๆถๅนถๆฒกๆ"ๆง่ก fork() ๅฝๆฐ" โ
โ ๅฎๅชๆฏ่ขซๅ
ๆ ธๆพๅฐไบๅฏ่ฟ่ก้ๅ (RUNNABLE)๏ผๅนถ่ฟๆฒก็ๆญฃ่ฟ่กใ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| (่ฐๅบฆๅจๅๆขๅฐๅญ่ฟ็จ)
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๅญ่ฟ็จ"ไธ CPU"ๆถ๏ผไป็จๆทๆ่ง่ง็๏ผ่ชๅทฑๅฐฑๅ"ไป fork() ่ฟๅ"๏ผ โ
โ โ
โ trapframe->a0 = 0 --> fork() ็่ฟๅๅผ==0 โ
โ โ
โ ๅญ่ฟ็จๅ
ถๅฎๆฏๅจ"็จๆทๆ็ fork() ่ฐ็จ็นไนๅ"็ปง็ปญๆง่ก๏ผ โ
โ ่ชๅทฑ็ๅฐ fork() ็่ฟๅๅผๆฏ 0 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## ็ถ่ฟ็จ่ง่ง
```c
// Create a new process, copying the parent.
// Sets up child kernel stack to return as if from fork() system call.
int
fork(void)
{
int i, pid;
struct proc *np;
struct proc *p = myproc(); //Process p = Process.currentProcess();
// Allocate process.
if((np = allocproc()) == 0){
return -1; //่ฟๅ -1 ่กจ็คบ้่ฏฏ
}
// Copy user memory from parent to child.
// ๅคๅถๅ
ๅญ็ฉบ้ด np.setMemory(p.getMemory().clone());
if(uvmcopy(p->pagetable, np->pagetable, p->sz) < 0){
freeproc(np);
release(&np->lock);
return -1;
}
np->sz = p->sz;
np->parent = p; //np.setParent(p);
np->mask = p->mask; //np.setMask(p.getMask());
// copy saved user registers.
*(np->trapframe) = *(p->trapframe);
// Cause fork to return 0 in the child.
// ไฟฎๆนๅญ่ฟ็จ่ฟ่พน็่ฟๅๅผ๏ผ
// ็ถ่ฟ็จๆฟๅฐ็ fork() ่ฟๅๅผๆฏ pid๏ผๅญ่ฟ็จๅๆฏ 0ใ่ฟๆฏ Unix fork() ็็ปๅ
ธ่ฏญไนใ
np->trapframe->a0 = 0;
// increment reference counts on open file descriptors.
for(i = 0; i < NOFILE; i++)
if(p->ofile[i])
// child.openFiles[i] = new FileDescriptor(parent.openFiles[i])
np->ofile[i] = filedup(p->ofile[i]);
np->cwd = idup(p->cwd);
safestrcpy(np->name, p->name, sizeof(p->name));
pid = np->pid;
np->state = RUNNABLE;
release(&np->lock);
return pid;
}
```
## ๅญ่ฟ็จ่ง่ง
```c
// ๅจๅญ่ฟ็จ trapframe ไธญๅฐ a0 ่ฎพไธบ 0
np->trapframe->a0 = 0;
```
่ฟไธๅ้ฝๅช้่ฆๅ
ๆ ธๅจ**็ถ่ฟ็จ็"fork"ไปฃ็ **้ๆๅญ่ฟ็จ็่ฟ่ก็ฐๅบ๏ผtrapframe๏ผ"ๆๅผ"ๅฅฝๅณๅฏ๏ผๅญ่ฟ็จ**ไธไผ**ๅจๅ
ๆ ธ้ๅๅป"่ตฐไธ้"ๅ็ปญ็่ตๅผใๅพช็ฏใreturn ็ญ C ไปฃ็ ใ
## ไธบไปไนๅญ่ฟ็จๆฟๅฐ็ fork() ่ฟๅๅผ 0
1. RISC-V ๆถๆไธญๅฝๆฐ่ฟๅๅผไฟๅญๅจ `a0`
2. ่ฟๅฐฑ่ฎฉๅญ่ฟ็จ็ๅฏๅญๅจ `a0` ่ขซๅผบ่ก็ฝฎๆ `0`ใ
3. ๅจ Unix ็่ฟ็จๆจกๅไธญ๏ผ"ๅญ่ฟ็จ"่ฏ็ๆถไป
ไป
ๆฏใๅคๅถไบ็ถ่ฟ็จ็ๅฐๅ็ฉบ้ดๅๅ
ๆ ธไธไธๆใ๏ผ่ชๅทฑ**่ฟๆฒก็ๆญฃ่ทๅพ CPU ๆง่กๆถ้ด**ใๅฎๅชๆๅจๅ
ๆ ธๆๅฎๆ ่ฎฐไธบ `RUNNABLE` ไนๅ๏ผ่ฐๅบฆๅจๆ่ฝๅจๅฐๆฅๆไธชๆถๅป"ๅๆข"ๅฐๅญ่ฟ็จ๏ผ่ฎฉๅฎ**ไป็จๆทๆ**่ท่ตทๆฅใ
4. ็ญๅญ่ฟ็จ่ฆ"่ฟๅๅฐ็จๆทๆ"ๆถ๏ผไผๆ `a0` ็ๅผๅธฆๅฐๅญ่ฟ็จ็ C ่ฐ็จๆ ็ฏๅข๏ผ**ไป่ๅญ่ฟ็จ็ๅฐ็ `fork()` ่ฟๅๅผๆฏ 0**ใ
ไนๅฐฑๆฏ่ฏด๏ผ่ฟไบ"ๆท่ดๅ
ๅญใ่ฎพ็ฝฎๅฏๅญๅจใ่ฎพ็ฝฎ่ฟๅๅผ"็ๅจไฝ๏ผ**ๆฌ่ดจๆฏ็ถ่ฟ็จๅจๅนฒ**๏ผๅญ่ฟ็จๅนถไธ้่ฆ"ไบฒๅไบฒไธบ"ใ
ๅ ๆญค๏ผไป
ๅญ
```c
np->trapframe->a0 = 0; // ๅฏนๅญ่ฟ็จ่ฎพ็ฝฎ่ฟๅๅผ
return pid; // ๅฏน็ถ่ฟ็จ่ฎพ็ฝฎ่ฟๅๅผ
```
ๅฐฑ่ฝๅจ็ถๅญไธคไธช่ฟ็จไธญไฝ็ฐไธๅ็่ฟๅๅผ๏ผ่พพๆ Unix `fork()` ็"ไธๆฌก่ฐ็จใไธคๆฌก่ฟๅ"ๆๆใ