Konsep Sistem Operasi dan APUE mengatakan
Dengan vfork (), proses induk ditangguhkan, dan proses anak menggunakan ruang alamat induk. Karena vfork () tidak menggunakan copy-on-write, jika proses anak mengubah halaman apa pun dari ruang alamat orang tua, halaman yang diubah akan terlihat oleh orang tua setelah resume. Oleh karena itu, vfork () harus digunakan dengan hati-hati untuk memastikan bahwa proses anak tidak mengubah ruang alamat orang tua.
vfork () dimaksudkan untuk digunakan ketika proses anak memanggil exec () atau keluar () segera setelah pembuatan.
Bagaimana saya bisa mengerti kalimat terakhir?
Ketika proses anak dibuat oleh vfork()
panggilan exec()
, tidak exec()
mengubah ruang alamat dari proses induk, dengan memuat program baru?
Ketika proses anak dibuat oleh vfork()
panggilan exit()
, exit()
tidak mengubah ruang alamat dari proses induk saat mengakhiri anak?
Saya lebih suka Linux.
Terima kasih.
posix_spawn
. Secara signifikan lebih sulit untuk menulis kode yang benar menggunakanposix_spawn
daripada dengan yang lamafork
, dan jika Anda mencoba, Anda mungkin mengalami tembok bata karena tidak ada file action atau atribut yang melakukan hal yang perlu Anda lakukan di antaranyafork
danexec
. Dan tidak dijamin memiliki efisiensi seperti vfork, sehingga tidak menyelesaikan masalah yang orang ingin atasi.posix_spawn
mungkin kekurangan fungsionalitas yang Anda inginkan (Anda dapat menyelesaikannya melalui program pembantu perantara, ditulis dalam C atau skrip shell inline-on-cmdline), segala upaya untuk mencapai apa yang Anda inginkan denganvfork
memanggil perilaku berbahaya yang tidak terdefinisi. Spesifikasi untukvfork
tidak memungkinkan memanggil fungsi acak untuk mengatur negara untuk anak untuk diwarisi sebelumnyaexecve
, dan upaya untuk melakukannya dapat merusak keadaan orang tua.posix_spawn
kinerja kira-kira sama denganvfork
di sebagian besar kondisi. Yang mana ada perbedaan cenderung menjadi kasus-kasus di manavfork
sangat tidak aman: di mana ada penangan sinyal diinstal yangposix_spawn
harus menekan agar tidak berjalan pada anak sebelum eksekutif.Saat Anda menelepon
vfork()
, proses baru dibuat dan proses baru itu meminjam gambar proses dari proses induk dengan pengecualian tumpukan. Proses anak diberi bintang stack baru sendiri namun tidak diizinkanreturn
dari fungsi yang dipanggilvfork()
.Saat anak berjalan, proses induk diblokir, karena anak meminjam ruang alamat dari induk.
Terlepas dari apa yang Anda lakukan, semua yang hanya mengakses tumpukan memodifikasi hanya tumpukan pribadi anak. Namun, jika Anda memodifikasi data global, ini memodifikasi data umum dan karenanya juga memengaruhi induknya.
Hal-hal yang mengubah data global adalah:
menelepon malloc () atau gratis ()
menggunakan stdio
memodifikasi pengaturan sinyal
memodifikasi variabel yang tidak lokal ke fungsi yang dipanggil
vfork()
....
Setelah Anda menelepon
_exit()
(penting, tidak pernah meneleponexit()
), anak tersebut dihentikan dan kontrol diberikan kembali kepada orang tua.Jika Anda memanggil fungsi apa pun dari
exec*()
keluarga, ruang alamat baru dibuat dengan kode program baru, data baru, dan bagian dari tumpukan dari induknya (lihat di bawah). Setelah ini siap, anak tidak lagi meminjam ruang alamat dari anak, tetapi menggunakan ruang alamat sendiri.Kontrol diberikan kembali ke induk, karena ruang alamat itu tidak lagi digunakan oleh proses lain.
Penting: Di Linux, tidak ada
vfork()
implementasi nyata . Linux lebih mengimplementasikanvfork()
berdasarkanfork()
konsep Copy on Write yang diperkenalkan oleh SunOS-4.0 pada tahun 1988. Untuk membuat pengguna percaya bahwa mereka menggunakanvfork()
, Linux hanya mengatur data bersama dan menangguhkan orang tua sementara anak tidak memanggil_exit()
atau salah satuexec*()
fungsi.Oleh karena itu Linux tidak mendapat manfaat dari kenyataan bahwa nyata
vfork()
tidak perlu mengatur deskripsi ruang alamat untuk anak di kernel. Ini menghasilkanvfork()
yang tidak lebih cepat darifork()
. Pada sistem yang mengimplementasikan nyatavfork()
, biasanya 3x lebih cepat darifork()
dan mempengaruhi kinerja shell yang menggunakanvfork()
-ksh93
, yang terbaruBourne Shell
dancsh
.Alasan mengapa Anda tidak boleh menelepon
exit()
darivfork()
anak ed adalah bahwaexit()
flushes stdio kalau-kalau ada data tidak rata dari waktu sebelum meneleponvfork()
. Ini dapat menyebabkan hasil yang aneh.BTW:
posix_spawn()
diimplementasikan di atasvfork()
, jadivfork()
tidak akan dihapus dari OS. Telah disebutkan bahwa Linux tidak digunakanvfork()
untukposix_spawn()
.Untuk tumpukan, ada beberapa dokumentasi, inilah yang dikatakan halaman manual Solaris:
Jadi implementasinya dapat melakukan apa pun yang disukainya. Implementasi Solaris menggunakan memori bersama untuk bingkai stack dari pemanggilan fungsi
vfork()
. Tidak ada implementasi yang memberikan akses ke bagian stack yang lebih lama dari induknya.sumber
posix_spawn()
di atas Linuxvfork()
. Mereka berdua mengimplementasikannya di atas__clone()
.vfork()
panggilan saja,clone()
bukan? Secara harfiah ini adalah one-liner di kernel.vfork
danfork
di Linux, itu melakukan sesuatu yang salah.