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 diizinkan return
dari fungsi yang dipanggil vfork()
.
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 menelepon exit()
), 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 mengimplementasikan vfork()
berdasarkan fork()
konsep Copy on Write yang diperkenalkan oleh SunOS-4.0 pada tahun 1988. Untuk membuat pengguna percaya bahwa mereka menggunakan vfork()
, Linux hanya mengatur data bersama dan menangguhkan orang tua sementara anak tidak memanggil _exit()
atau salah satu exec*()
fungsi.
Oleh karena itu Linux tidak mendapat manfaat dari kenyataan bahwa nyata vfork()
tidak perlu mengatur deskripsi ruang alamat untuk anak di kernel. Ini menghasilkan vfork()
yang tidak lebih cepat dari fork()
. Pada sistem yang mengimplementasikan nyata vfork()
, biasanya 3x lebih cepat dari fork()
dan mempengaruhi kinerja shell yang menggunakan vfork()
- ksh93
, yang terbaru Bourne Shell
dan csh
.
Alasan mengapa Anda tidak boleh menelepon exit()
dari vfork()
anak ed adalah bahwa exit()
flushes stdio kalau-kalau ada data tidak rata dari waktu sebelum menelepon vfork()
. Ini dapat menyebabkan hasil yang aneh.
BTW: posix_spawn()
diimplementasikan di atas vfork()
, jadi vfork()
tidak akan dihapus dari OS. Telah disebutkan bahwa Linux tidak digunakan vfork()
untuk posix_spawn()
.
Untuk tumpukan, ada beberapa dokumentasi, inilah yang dikatakan halaman manual Solaris:
The vfork() and vforkx() functions can normally be used the
same way as fork() and forkx(), respectively. The calling
procedure, however, should not return while running in the
child's context, since the eventual return from vfork() or
vforkx() in the parent would be to a stack frame that no
longer exists.
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.