Saya mencari untuk menemukan perbedaan antara keempat ini di Google dan saya berharap akan ada sejumlah besar informasi tentang ini, tetapi benar-benar tidak ada perbandingan yang kuat antara keempat panggilan.
Saya mulai mencoba mengkompilasi tampilan dasar sekilas perbedaan antara panggilan sistem dan inilah yang saya dapatkan. Apakah semua informasi ini benar / apakah saya melewatkan sesuatu yang penting?
Fork
: Panggilan garpu pada dasarnya membuat duplikat dari proses saat ini, identik dalam hampir setiap cara (tidak semuanya disalin, misalnya, batas sumber daya dalam beberapa implementasi tetapi idenya adalah untuk membuat salinan sedekat mungkin).
Proses baru (anak) mendapatkan ID proses (PID) yang berbeda dan memiliki PID dari proses lama (induk) sebagai induk PID (PPID). Karena kedua proses sekarang menjalankan kode yang persis sama, mereka dapat mengetahui yang mana dengan kode pengembalian garpu - anak mendapat 0, orang tua mendapat PID anak. Ini semua, tentu saja, dengan asumsi panggilan garpu berfungsi - jika tidak, tidak ada anak yang dibuat dan orang tua mendapat kode kesalahan.
Vfork
: Perbedaan mendasar antara vfork dan fork adalah ketika proses baru dibuat dengan vfork (), proses induk ditangguhkan sementara, dan proses anak mungkin meminjam ruang alamat orangtua. Keadaan aneh ini berlanjut hingga proses anak keluar, atau panggilan execve (), di mana proses induk berlanjut.
Ini berarti bahwa proses turunan vfork () harus berhati-hati untuk menghindari variabel tak terduga memodifikasi proses induk. Secara khusus, proses anak tidak boleh kembali dari fungsi yang berisi panggilan vfork (), dan itu tidak boleh memanggil keluar () (jika perlu keluar, harus menggunakan _exit (); sebenarnya, ini juga berlaku untuk anak dari garpu normal ()).
Exec :
Panggilan exec adalah cara untuk mengganti seluruh proses saat ini dengan program baru. Itu memuat program ke dalam ruang proses saat ini dan menjalankannya dari titik masuk. exec () menggantikan proses saat ini dengan executable yang ditunjuk oleh fungsi. Kontrol tidak pernah kembali ke program semula kecuali ada kesalahan exec ().
Clone :
Clone, seperti garpu, menciptakan proses baru. Tidak seperti garpu, panggilan ini memungkinkan proses anak untuk berbagi bagian dari konteks eksekusi dengan proses panggilan, seperti ruang memori, tabel deskriptor file, dan tabel penangan sinyal.
Ketika proses anak dibuat dengan klon, ia mengeksekusi aplikasi fungsi fn (arg). (Ini berbeda dari garpu, di mana eksekusi berlanjut pada anak dari titik panggilan garpu asli.) Argumen fn adalah penunjuk ke fungsi yang dipanggil oleh proses anak pada awal pelaksanaannya. Argumen argumen diteruskan ke fungsi fn.
Ketika aplikasi fungsi fn (arg) kembali, proses anak berakhir. Integer yang dikembalikan oleh fn adalah kode keluar untuk proses anak. Proses anak juga dapat berakhir secara eksplisit dengan memanggil keluar (2) atau setelah menerima sinyal fatal.
Informasi yang diperoleh:
- Perbedaan antara garpu dan exec
- http://www.allinterview.com/showanswers/59616.html
- http://www.unixguide.net/unix/programming/1.1.2.shtml
- http://linux.about.com/library/cmd/blcmdl2_clone.htm
Terima kasih telah meluangkan waktu untuk membaca ini! :)
fork()
, yang ada di Linux, dan mungkin semua BSD) meminjam ruang alamat orang tuanya. Apa pun yang dilakukannya, selain meneleponexecve()
atau_exit()
, memiliki potensi besar untuk mengacaukan orangtua. Secara khusus,exit()
panggilanatexit()
penangan dan "finalizer" lainnya, misalnya: ia menyiram aliran stdio. Kembali dari seorangvfork()
anak akan berpotensi (peringatan yang sama seperti sebelumnya) mengacaukan tumpukan orangtua.fork
syscall?Jawaban:
vfork()
adalah optimasi usang. Sebelum manajemen memori yang baik,fork()
buat salinan lengkap dari memori orang tua, jadi itu cukup mahal. karena dalam banyak kasus afork()
diikuti olehexec()
, yang membuang peta memori saat ini dan membuat yang baru, itu adalah pengeluaran yang tidak perlu. Saat ini,fork()
jangan menyalin memori; itu hanya ditetapkan sebagai "copy on write", jadifork()
+exec()
seefisienvfork()
+exec()
.clone()
adalah syscall yang digunakan olehfork()
. dengan beberapa parameter, itu menciptakan proses baru, dengan yang lain, itu menciptakan utas. perbedaan di antara mereka hanyalah struktur data (ruang memori, keadaan prosesor, tumpukan, PID, file terbuka, dll) yang dibagikan atau tidak.sumber
vfork
menghindari kebutuhan untuk sementara melakukan lebih banyak memori hanya supaya seseorang dapat mengeksekusiexec
, dan itu masih lebih efisien daripadafork
, bahkan jika tidak hampir setinggi gelar. Dengan demikian, seseorang dapat menghindari keharusan terlalu banyak memori sehingga program besar sebong bisa menelurkan proses anak. Jadi, bukan hanya peningkatan kinerja, tetapi mungkin membuatnya layak sama sekali.exec
.execve()
mengganti gambar yang dapat dieksekusi saat ini dengan yang lain diambil dari file yang dapat dieksekusi.fork()
menciptakan proses anak.vfork()
adalah versi yang dioptimalkan secara historisfork()
, dimaksudkan untuk digunakan ketikaexecve()
dipanggil langsung setelahnyafork()
. Ternyata bekerja dengan baik dalam sistem non-MMU (di manafork()
tidak dapat bekerja secara efisien) dan ketikafork()
proses dengan jejak memori besar untuk menjalankan beberapa program kecil (pikirkan JavaRuntime.exec()
). POSIX telah membuat standarposix_spawn()
untuk menggantikan dua penggunaan yang lebih modern inivfork()
.posix_spawn()
tidak sama dengan afork()/execve()
, dan juga memungkinkan beberapa juggling fd di antaranya. Itu seharusnya digantifork()/execve()
, terutama untuk platform non-MMU.pthread_create()
membuat utas baru.clone()
adalah panggilan khusus Linux, yang dapat digunakan untuk mengimplementasikan apa saja darifork()
kepthread_create()
. Ini memberi banyak kontrol. Terinspirasi padarfork()
.rfork()
adalah panggilan khusus Plan-9. Seharusnya panggilan umum, memungkinkan beberapa derajat berbagi, antara proses penuh dan utas.sumber
fork()
- Membuat proses anak baru, yang merupakan salinan lengkap dari proses induk. Proses anak dan orang tua menggunakan ruang alamat virtual yang berbeda, yang awalnya diisi oleh halaman memori yang sama. Kemudian, ketika kedua proses dieksekusi, ruang alamat virtual mulai berbeda semakin banyak, karena sistem operasi melakukan penyalinan malas dari halaman memori yang sedang ditulis oleh salah satu dari kedua proses ini dan memberikan salinan independen dari halaman yang dimodifikasi dari memori untuk setiap proses. Teknik ini disebut Copy-On-Write (COW).vfork()
- membuat proses anak baru, yang merupakan salinan "cepat" dari proses induk. Berbeda dengan panggilan sistemfork()
, proses anak dan orang tua berbagi ruang alamat virtual yang sama. CATATAN! Menggunakan ruang alamat virtual yang sama, orang tua dan anak menggunakan tumpukan yang sama, penunjuk tumpukan dan penunjuk instruksi, seperti dalam kasus klasikfork()
! Untuk mencegah gangguan yang tidak diinginkan antara orang tua dan anak, yang menggunakan tumpukan yang sama, eksekusi proses induk dibekukan sampai anak akan memanggil salah satuexec()
(membuat ruang alamat virtual baru dan transisi ke tumpukan yang berbeda) atau_exit()
(penghentian proses eksekusi ).vfork()
adalah optimalisasifork()
untuk model "fork-and-exec". Ini dapat dilakukan 4-5 kali lebih cepat daripadafork()
, karena tidak sepertifork()
(bahkan dengan SAP tetap diingat), implementasivfork()
system call tidak termasuk pembuatan ruang alamat baru (alokasi dan pengaturan direktori halaman baru).clone()
- menciptakan proses anak baru. Berbagai parameter panggilan sistem ini, menentukan bagian mana dari proses induk harus disalin ke proses anak dan bagian mana yang akan dibagikan di antara mereka. Sebagai hasilnya, pemanggilan sistem ini dapat digunakan untuk membuat semua jenis entitas eksekusi, mulai dari utas dan finishing dengan proses yang sepenuhnya independen. Bahkan,clone()
system call adalah basis yang digunakan untuk implementasipthread_create()
dan semua keluargafork()
panggilan sistem.exec()
- me-reset semua memori dari proses, memuat dan mem-parsing biner yang dapat dieksekusi, mengatur stack baru dan melewati kontrol ke titik masuknya executable yang dimuat. Panggilan sistem ini tidak pernah mengembalikan kontrol ke penelepon dan berfungsi untuk memuat program baru ke proses yang sudah ada. Panggilan sistem ini dengan panggilanfork()
sistem bersama-sama membentuk model manajemen proses UNIX klasik yang disebut "fork-and-exec".sumber
vfork
begitu lemah sehingga akan sah untuk membuatvfork
sinonim darifork
(dan POSIX.1-2008 menghapusvfork
sepenuhnya dari spesifikasi). Jika Anda menguji kode Anda pada sistem yang mensinonimkannya (mis. Sebagian besar pasca-4.4 BSD selain dari NetBSD, kernel Linux pra-2.2.0-pre6, dll.), Itu dapat berfungsi bahkan jika Anda melanggarvfork
kontrak, kemudian meledak jika Anda menjalankannya di tempat lain. Beberapa dari mereka yang mensimulasikan denganfork
(misalnya OpenBSD) masih menjamin orang tua tidak kembali berjalan sampai anakexec
s atau_exit
s. Ini sangat non-portabel.Garpu (), vfork () dan klon () semuanya memanggil do_fork () untuk melakukan pekerjaan nyata, tetapi dengan parameter yang berbeda.
Untuk garpu, anak dan ayah memiliki tabel halaman VM independen, tetapi karena efisiensi, garpu tidak akan benar-benar menyalin halaman, itu hanya mengatur semua halaman yang dapat ditulis untuk dibaca hanya untuk proses anak. Jadi ketika proses anak ingin menulis sesuatu di halaman itu, pengecualian halaman terjadi dan kernel akan mengalokasikan halaman baru yang dikloning dari halaman lama dengan izin menulis. Itu disebut "copy on write".
Untuk vfork, memori virtual persis oleh anak dan ayah --- hanya karena itu, ayah dan anak tidak dapat bangun secara bersamaan karena mereka akan saling mempengaruhi. Jadi ayah akan tidur di akhir "do_fork ()" dan bangun ketika child call keluar () atau execve () karena kemudian akan memiliki tabel halaman baru. Berikut adalah kode (dalam do_fork ()) yang ayah tidur.
Berikut adalah kode (dalam mm_release () dipanggil oleh exit () dan execve ()) yang membangunkan ayah.
Untuk sys_clone (), ini lebih fleksibel karena Anda dapat memasukkan clone_flags apa pun ke dalamnya. Jadi pthread_create () panggil panggilan sistem ini dengan banyak clone_flags:
int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM);
Ringkasan: fork (), vfork () dan clone () akan membuat proses anak dengan berbagai sumber daya berbagi dengan proses ayah. Kita juga dapat mengatakan vfork () dan clone () dapat membuat utas (sebenarnya mereka adalah proses karena mereka memiliki task_struct independen) karena mereka berbagi tabel halaman VM dengan proses ayah.
sumber
di fork (), proses anak atau orang tua akan mengeksekusi berdasarkan pemilihan cpu .. Tapi di vfork (), pasti anak akan mengeksekusi terlebih dahulu. setelah anak dihentikan, orang tua akan mengeksekusi.
sumber
vfork()
hanya bisa diimplementasikan sebagaifork()
.pid
) - sistem operasi dapat menjadwalkan proses baru untuk berjalan secara paralel jika hal seperti itu masuk akal (misalnya, beberapa prosesor). Jika karena alasan tertentu Anda memerlukan proses ini untuk dieksekusi dalam urutan serial tertentu, maka Anda perlu sinkronisasi tambahan yang tidak disediakan forking; terus terang, Anda mungkin bahkan tidak ingin garpu di tempat pertama.vfork()
, anak berlari pertama. Itu ada di halaman manual; eksekusi orang tua ditunda sampai anak meninggal atauexec
s. Dan ninjalj mencari kode sumber kernel. Tidak ada cara untuk menerapkanvfork()
sebagaifork()
karena mereka melewati argumen yang berbeda untukdo_fork()
dalam kernel. Anda dapat, bagaimanapun, menerapkanvfork
denganclone
syscall