Это не так сложно, правда - половина ядра системного вызова fork () может показать разницу между двумя процессами через блок управления процессами, как вы упомянули, но вам даже не нужно этого делать. Таким образом, псевдокод выглядит так:
int fork()
{
int orig_pid = getpid();
int new_pid = kernel_do_fork(); // Now there's two processes
// Remember, orig_pid is the same in both procs
if (orig_pid == getpid()) {
return new_pid;
}
// Must be the child
return 0;
}
Edit:
Наивная версия работает так же, как вы описываете - она создает новый контекст процесса, копирует все связанные контексты потока, копирует все страницы и сопоставления файлов, и новый процесс помещается в список «готов к запуску».
Я думаю, что часть, из-за которой вы запутались, заключается в том, что когда эти процессы возобновляются (то есть, когда родитель возвращается из kernel_do_fork, а потом запланирован первый раз), он начинается в middle функции (т.е. выполнение этого первого «если»). Это точная копия - оба процесса выполнят вторую половину функции.