Apa perbedaan antara fork () dan vfork ()?

13

Saya ingin memahami secara detail perbedaan antara fork () dan vfork (). Saya tidak dapat mencerna halaman manual sepenuhnya.

Saya juga ingin mengklarifikasi komentar salah satu kolega saya " Di Linux saat ini, tidak ada vfork (), bahkan jika Anda menyebutnya, secara internal ia akan memanggil fork () ."

Sen
sumber

Jawaban:

24

Halaman manual biasanya merupakan dokumen referensi singkat. Wikipedia adalah tempat yang lebih baik untuk mencari penjelasan konseptual.

Fork menduplikasi suatu proses: itu menciptakan proses anak yang hampir identik dengan proses induk (perbedaan yang paling jelas adalah bahwa proses baru memiliki ID proses yang berbeda). Secara khusus, garpu (secara konseptual) harus menyalin semua memori proses induk.

Karena ini agak mahal, vfork diciptakan untuk menangani kasus khusus umum di mana salinannya tidak diperlukan. Seringkali, hal pertama yang dilakukan proses anak adalah memuat gambar program baru, jadi inilah yang terjadi:

if (fork()) {
    # parent process …
} else {
    # child process (with a new copy of the process memory)
    execve("/bin/sh", …);  # discard the process memory
}

The execvepanggilan beban program executable baru, dan menggantikan ini proses kode dan data memori dengan kode executable baru dan memori data segar. Jadi seluruh salinan memori yang dibuat oleh forksemua untuk apa-apa.

Jadi vforkpanggilan itu diciptakan. Itu tidak membuat salinan dari memori. Karena vforkitu murah, tetapi sulit digunakan karena Anda harus memastikan Anda tidak mengakses tumpukan proses atau ruang tumpukan dalam proses anak. Perhatikan bahwa bahkan membaca dapat menjadi masalah, karena proses induk terus dijalankan. Sebagai contoh, kode ini rusak (mungkin atau tidak dapat bekerja tergantung pada apakah anak atau orang tua mendapat potongan waktu terlebih dahulu):

if (vfork()) {
    # parent process
    cmd = NULL; # modify the only copy of cmd
} else {
    # child process
    execve("/bin/sh", "sh", "-c", cmd, (char*)NULL);  # read the only copy of cmd
}

Sejak penemuan vfork, optimalisasi yang lebih baik telah ditemukan. Sebagian besar sistem modern, termasuk Linux, menggunakan bentuk copy-on-write , di mana halaman dalam memori proses tidak disalin pada saat forkpanggilan, tetapi kemudian ketika orang tua atau anak pertama kali menulis ke halaman. Yaitu, setiap halaman dimulai sebagai dibagikan, dan tetap dibagikan sampai proses menulis ke halaman itu; proses yang menulis mendapat halaman fisik baru (dengan alamat virtual yang sama). Copy-on-write membuat vfork sebagian besar tidak berguna, karena forktidak akan membuat salinan dalam kasus di mana vforkakan dapat digunakan.

Linux mempertahankan vfork. The forksystem call masih harus membuat salinan dari proses ini tabel memori virtual, bahkan jika itu tidak menyalin memori yang sebenarnya; vforkbahkan tidak perlu melakukan ini. Peningkatan kinerja dapat diabaikan di sebagian besar aplikasi.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Terima kasih atas jawaban yang brilian ini .. Saat melakukan fork (), anak itu akan mendapatkan ID proses baru dan ruang Virtual yang terkait, lalu mengapa ia masih harus membuat salinan tabel memori virtual proses? Saya tidak jelas di bagian itu.
Sen
@ Sen: forkperlu membuat pemetaan memori virtual terpisah sehingga salinan copy-on-write berikutnya hanya mempengaruhi salah satu dari dua proses.
Gilles 'SANGAT berhenti menjadi jahat'
Anda yakin proses induk berjalan?
qbolec
2

The fork()dan vfork()syscalls berbeda.

The fork()syscall menghasilkan dua proses yang identik dengan memori yang terpisah. The vfork()syscall menghasilkan dua proses yang berbagi memori yang sama.

Dengan vfork()orang tua akan menunggu anak berakhir. Induk mewarisi dari variabel yang dibagikan program. Jadi setelah anak dipanggil, semua variabel yang dimodifikasi di dalam anak akan tetap dimodifikasi di dalam induknya.

Untuk informasi lebih lanjut klik di sini

Yogeesh HT
sumber