2010-02-05 22 views
6

Wiem, co robi fork() na wyższym poziomie. Co chciałbym wiedzieć, jest to -co dzieje się na niższych poziomach po wywołaniu systemu fork?

  1. Jak tylko tam jest wezwaniem widelec, instrukcja trap następuje kontrola i przeskakuje do wykonania stołu „obsługi”. Teraz, w jaki sposób ten handler, który tworzy proces potomny, przez powielenie procesu nadrzędnego przez utworzenie innej przestrzeni adresowej i bloku sterowania procesem, zwraca 2 wartości, po jednej do każdego procesu?

  2. Do jakiego momentu wykonania widelec zwraca 2 wartości?

Czy można wyjaśnić krok po kroku zdarzenia, które mają miejsce na niższym poziomie po wywołaniu wideł?

Odpowiedz

1

To nie jest tak trudne, prawda - jądro połówki widelca() syscall może odróżnić te dwa procesy za pośrednictwem bloku sterowania procesem, jak wspomniano, ale nie trzeba tego nawet robić. Więc pseudokod wygląda następująco:

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: Wersja naiwny robi tak jak opisują - tworzy nowy kontekst procesu, kopie wszystkich związanych kontekstach gwintów, kopie wszystkich stron i mapowania plików , a nowy proces zostaje umieszczony na liście "gotowy do uruchomienia".

myślę, że część jesteś coraz mylić na to, że kiedy te procesy wznowić (czyli gdy rodzic wraca z kernel_do_fork, a dziecko jest zaplanowane po raz pierwszy), to zaczyna się w środkowej z funkcja (tj. wykonanie tego pierwszego "jeśli"). Jest to kopia dokładna - oba procesy wykonają drugą połowę funkcji.

+0

możesz mi powiedzieć, co to jest kernel_do_fork()? Czy nie nazywa się rekursywnie? –

+0

Dzięki za poświęcenie czasu na wyjaśnienie Paula. –

1

Wartość zwrócona do każdego procesu jest inna. Wątek nadrzędny/oryginalny otrzymuje identyfikator PID procesu podrzędnego, a proces podrzędny otrzymuje 0.

Jądro systemu Linux osiąga to na x86, zmieniając wartość w rejestrze eax jako copies the current thread w procesie nadrzędnym.

Powiązane problemy