Ce face os.fork() și os.register_at_fork()
fork() duplică procesul. În copil, funcția returnează 0; în părinte, returnează PID-ul copilului. Copilul are o copie a memoriei părintelui, inclusiv a textului care încă așteaptă în tamponul lui print; de aceea golește tamponul (flush=True) înainte de fork și în copil, înainte de os._exit(). Părintele așteaptă copilul cu os.waitpid(), ca să nu rămână procese „zombie”.
register_at_fork() înregistrează funcții apelate înainte de fork și după el, în părinte și în copil, de exemplu pentru a reinițializa conexiuni. fork într-un program cu mai multe fire este riscant (Python 3.12+ afișează DeprecationWarning); multiprocessing și subprocess sunt alternative sigure.
Ce returnează
0 în copil, PID-ul copilului în părinte.
Exemple
Exemplul 1: Părinte și copil
import os
os.register_at_fork(after_in_child=lambda: print("[hook] sunt copilul", flush=True))
valoare = 10
pid = os.fork()
if pid == 0:
valoare += 5
print("copil, valoare =", valoare, flush=True)
os._exit(3)
_, stare = os.waitpid(pid, 0)
print("părinte, valoare =", valoare, "| copilul a ieșit cu", os.waitstatus_to_exitcode(stare))
Rezultat
[hook] sunt copilul
copil, valoare = 15
părinte, valoare = 10 | copilul a ieșit cu 3
Greșeli frecvente
- Copilul se termină cu
sys.exit()sau ajunge la finalul scriptului și rulează și codul destinat părintelui. Foloseșteos._exit()în copil.
Comenzi înrudite
os.wait(), waitpid(), wait3(), wait4(), waitid() și waitstatus_to_exitcode(): Așteaptă terminarea proceselor copil și află cum s-au terminat.Familia os.exec*: execv(), execvp(), execl()...: Înlocuiește programul curent cu alt program; codul de după apel nu mai rulează.subprocess.run(): Pornește un program extern, așteaptă să se termine și îi returnează rezultatul.os.pipe(): Creează o „țeavă” anonimă: ce scrii la un capăt citești la celălalt.