[Aku akan mengulangi sebagian dari jawabanku dari sini .]
Mengapa tidak hanya memiliki perintah yang menciptakan proses baru dari awal? Bukankah tidak masuk akal dan tidak efisien untuk menyalin satu yang hanya akan segera diganti?
Bahkan, itu mungkin tidak seefisien karena beberapa alasan:
"Copy" yang diproduksi oleh fork()
adalah sedikit abstraksi, karena kernel menggunakan copy-on-write sistem ; semua yang benar-benar harus dibuat adalah peta memori virtual. Jika salinan kemudian segera memanggil exec()
, sebagian besar data yang akan disalin jika telah dimodifikasi oleh aktivitas proses tidak pernah benar-benar harus disalin / dibuat karena proses tidak melakukan apa pun yang memerlukan penggunaannya.
Berbagai aspek penting dari proses anak (misalnya, lingkungannya) tidak harus diduplikasi secara individual atau ditetapkan berdasarkan analisis konteks yang kompleks, dll. Mereka hanya diasumsikan sama dengan proses pemanggilan, dan ini adalah sistem yang cukup intuitif yang kita kenal.
Untuk menjelaskan # 1 sedikit lebih jauh, memori yang "disalin" tetapi tidak pernah diakses tidak pernah benar-benar disalin, setidaknya dalam banyak kasus. Pengecualian dalam konteks ini mungkin jika Anda melakukan proses bercabang, maka proses induk harus keluar sebelum anak diganti dengan sendiri exec()
. Saya katakan mungkin karena banyak dari orang tua bisa di-cache jika ada memori bebas yang cukup, dan saya tidak yakin sejauh mana ini akan dieksploitasi (yang akan tergantung pada implementasi OS).
Tentu saja, itu tidak di permukaan membuat menggunakan salinan lebih efisien daripada menggunakan batu tulis kosong - kecuali "batu tulis kosong" secara harfiah bukan apa-apa, dan harus melibatkan alokasi. Sistem dapat memiliki templat proses kosong / baru generik yang disalin dengan cara yang sama, 1 tetapi kemudian tidak akan benar-benar menyimpan apa pun dibandingkan garpu copy-on-write. Jadi # 1 hanya menunjukkan bahwa menggunakan proses kosong "baru" tidak akan lebih efisien.
Butir # 2 menjelaskan mengapa menggunakan garpu kemungkinan lebih efisien. Lingkungan anak diwarisi dari orang tuanya, bahkan jika itu adalah eksekusi yang sama sekali berbeda. Misalnya, jika proses induk adalah shell, dan anak itu browser web, $HOME
masih sama untuk keduanya, tetapi karena keduanya kemudian dapat mengubahnya, ini harus dua salinan terpisah. Yang ada di anak diproduksi oleh aslinya fork()
.
1. Strategi yang mungkin tidak masuk akal secara literal, tetapi poin saya adalah menciptakan sebuah proses melibatkan lebih dari menyalin gambar itu ke dalam memori dari disk.