Apa tujuan dari fork ()?

88

Di banyak program dan halaman manual Linux, saya telah melihat penggunaan kode fork(). Mengapa kita perlu menggunakan fork()dan apa tujuannya?

senfo
sumber
151
Agar semua filsuf makan itu tidak kelaparan.
kenj0418

Jawaban:

109

fork()adalah cara Anda membuat proses baru di Unix. Saat Anda menelepon fork, Anda membuat salinan proses Anda sendiri yang memiliki ruang alamatnya sendiri . Hal ini memungkinkan banyak tugas untuk berjalan secara independen satu sama lain seolah-olah mereka masing-masing memiliki memori penuh dari mesin itu sendiri.

Berikut adalah beberapa contoh penggunaan fork:

  1. Shell Anda digunakan forkuntuk menjalankan program yang Anda panggil dari baris perintah.
  2. Server web seperti apache digunakan forkuntuk membuat beberapa proses server, yang masing-masing menangani permintaan di ruang alamatnya sendiri. Jika satu mati atau kebocoran memori, yang lain tidak terpengaruh, sehingga berfungsi sebagai mekanisme toleransi kesalahan.
  3. Google Chrome digunakan forkuntuk menangani setiap halaman dalam proses terpisah. Ini akan mencegah kode sisi klien pada satu halaman menurunkan seluruh browser Anda.
  4. forkdigunakan untuk menelurkan proses di beberapa program paralel (seperti yang ditulis menggunakan MPI ). Perhatikan bahwa ini berbeda dengan menggunakan utas , yang tidak memiliki ruang alamat sendiri dan ada dalam suatu proses.
  5. Bahasa skrip digunakan forksecara tidak langsung untuk memulai proses anak. Misalnya, setiap kali Anda menggunakan perintah seperti subprocess.Popendi Python, Anda forkmerupakan proses anak dan membaca keluarannya. Ini memungkinkan program untuk bekerja sama.

Penggunaan umum forkdi shell mungkin terlihat seperti ini:

Shell memunculkan proses anak menggunakan execdan menunggu sampai selesai, lalu melanjutkan dengan eksekusinya sendiri. Perhatikan bahwa Anda tidak harus menggunakan garpu dengan cara ini. Anda selalu dapat mengeluarkan banyak proses anak, seperti yang mungkin dilakukan oleh program paralel, dan masing-masing dapat menjalankan program secara bersamaan. Pada dasarnya, setiap kali Anda membuat proses baru dalam sistem Unix, Anda menggunakan fork(). Untuk Windows yang setara, lihat CreateProcess.

Jika Anda menginginkan lebih banyak contoh dan penjelasan yang lebih panjang, Wikipedia memiliki ringkasan yang layak. Dan berikut adalah beberapa slide di sini tentang cara kerja proses, utas, dan konkurensi dalam sistem operasi modern.

Todd Gamblin
sumber
Butir 5: 'sering'? Hanya 'sering'? Yang mana yang tidak menggunakannya, atau dalam keadaan apa fork () tidak digunakan - pada sistem yang mendukung fork ().
Jonathan Leffler
19
Anehnya, ini disebut CreateProcess () - orang-orang Windows gila itu :-)
paxdiablo
2
tidak pernah menyadari sampai sekarang bahwa "shell menggunakan fork untuk menjalankan program yang Anda panggil dari baris perintah"!
Lazer
1
Tautan slide rusak
piertoni
1
Semua jawaban mengatakan bahwa fork()adalah cara untuk membuat proses baru di UNIX, tetapi untuk menjadi bertele-tele, ada setidaknya satu lainnya: posix_spawn().
Davislor
15

fork () adalah cara Unix membuat proses baru. Pada titik yang Anda panggil fork (), proses Anda dikloning, dan dua proses berbeda melanjutkan eksekusi dari sana. Salah satunya, anak, akan memiliki fork () return 0. Yang lainnya, orang tua, akan memiliki fork () mengembalikan PID (ID proses) anak.

Misalnya, jika Anda mengetik berikut ini di shell, program shell akan memanggil fork (), dan kemudian menjalankan perintah yang Anda berikan (telnetd, dalam hal ini) pada anak, sementara orang tua akan menampilkan prompt lagi, juga sebagai pesan yang menunjukkan PID dari proses latar belakang.

Adapun alasan Anda membuat proses baru, begitulah cara sistem operasi Anda dapat melakukan banyak hal pada saat yang bersamaan. Itulah mengapa Anda dapat menjalankan program dan, saat sedang berjalan, beralihlah ke jendela lain dan lakukan sesuatu yang lain.

Daniel C. Sobral
sumber
@varDumper Tangkapan bagus!
Daniel C. Sobral
9

fork () digunakan untuk membuat proses anak. Ketika fungsi fork () dipanggil, proses baru akan muncul dan pemanggilan fungsi fork () akan mengembalikan nilai yang berbeda untuk anak dan induk.

Jika nilai yang dikembalikan adalah 0, Anda tahu bahwa Anda adalah proses anak dan jika nilai yang dikembalikan adalah angka (yang kebetulan merupakan id proses anak), Anda tahu bahwa Anda adalah orang tuanya. (dan jika itu adalah angka negatif, garpu gagal dan tidak ada proses turunan yang dibuat)

http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html

Wadih M.
sumber
1
Kecuali nilai yang dikembalikan -1, dalam hal ini fork () gagal.
Jonathan Leffler
8

fork () pada dasarnya digunakan untuk membuat proses anak untuk proses di mana Anda memanggil fungsi ini. Setiap kali Anda memanggil fork (), itu mengembalikan nol untuk id anak.

dengan ini, Anda dapat memberikan tindakan yang berbeda untuk induk dan anak dan memanfaatkan fitur multithreading.

Nave
sumber
6

fork () akan membuat proses anak baru yang identik dengan induknya. Jadi semua yang Anda jalankan dalam kode setelah itu akan dijalankan oleh kedua proses - sangat berguna jika Anda memiliki misalnya server, dan Anda ingin menangani banyak permintaan.

cloudhead
sumber
mengapa kamu membuat anak yang identik dengan orang tua apa gunanya?
1
Ini seperti membangun pasukan vs seorang prajurit. Anda bercabang sehingga program Anda dapat menangani lebih banyak permintaan pada saat yang sama, bukan satu per satu.
cloudhead
fork () mengembalikan 0 pada anak dan pid anak pada induk. Anak itu kemudian dapat menggunakan panggilan seperti exec () untuk mengganti statusnya dengan program baru. Beginilah cara program diluncurkan.
Todd Gamblin
Prosesnya sangat mirip, tetapi ada banyak perbedaan kecil. Perbedaan mencolok adalah PID saat ini dan PID induk. Ada masalah yang terkait dengan kunci yang ditahan dan semafor yang ditahan. Halaman manual fork () untuk POSIX mendaftar 25 perbedaan antara induk dan anak.
Jonathan Leffler
2
@ Kar: Setelah Anda memiliki dua proses, mereka dapat melanjutkan secara terpisah dari sana dan salah satunya dapat menggantikan dirinya sendiri (exex ()) dengan program lain sepenuhnya.
Vatine
4

Anda mungkin tidak perlu menggunakan garpu dalam pemrograman sehari-hari jika Anda menulis aplikasi.

Bahkan jika Anda ingin program Anda memulai program lain untuk melakukan beberapa tugas, ada antarmuka lain yang lebih sederhana yang menggunakan garpu di belakang layar, seperti "sistem" di C dan perl.

Misalnya, jika Anda ingin aplikasi Anda meluncurkan program lain seperti bc untuk melakukan beberapa kalkulasi untuk Anda, Anda dapat menggunakan 'sistem' untuk menjalankannya. Sistem melakukan 'garpu' untuk membuat proses baru, lalu 'exec' untuk mengubah proses itu menjadi bc. Setelah bc selesai, sistem mengembalikan kontrol ke program Anda.

Anda juga dapat menjalankan program lain secara asinkron, tetapi saya tidak ingat caranya.

Jika Anda menulis server, shell, virus atau sistem operasi, kemungkinan besar Anda ingin menggunakan fork.

Alex Brown
sumber
Terima kasih untuk system(). Saya membaca tentang fork()karena saya ingin kode C saya menjalankan skrip python.
Taksi Kacang
4

Fork membuat proses baru. Tanpa fork Anda akan memiliki sistem unix yang hanya dapat menjalankan init.

Stephen
sumber
4

Sistem call fork () digunakan untuk membuat proses. Tidak membutuhkan argumen dan mengembalikan ID proses. Tujuan dari fork () adalah untuk membuat proses baru, yang menjadi proses anak pemanggil. Setelah proses anak baru dibuat, kedua proses akan menjalankan instruksi selanjutnya mengikuti panggilan sistem fork (). Oleh karena itu, kita harus membedakan orang tua dengan anak. Ini bisa dilakukan dengan menguji nilai yang dikembalikan dari fork ():

Jika fork () mengembalikan nilai negatif, pembuatan proses anak tidak berhasil. fork () mengembalikan nol ke proses anak yang baru dibuat. fork () mengembalikan nilai positif, ID proses dari proses anak, ke induk. ID proses yang dikembalikan adalah tipe pid_t yang didefinisikan di sys / types.h. Biasanya, ID proses adalah bilangan bulat. Selain itu, sebuah proses dapat menggunakan fungsi getpid () untuk mengambil ID proses yang ditetapkan untuk proses ini. Oleh karena itu, setelah panggilan sistem ke fork (), pengujian sederhana dapat mengetahui proses mana yang merupakan anak. Harap dicatat bahwa Unix akan membuat salinan persis dari ruang alamat orang tua dan memberikannya kepada anak tersebut. Oleh karena itu, proses induk dan anak memiliki ruang alamat yang terpisah.

Mari kita pahami dengan contoh untuk memperjelas poin di atas. Contoh ini tidak membedakan proses induk dan anak.

Misalkan program di atas mengeksekusi hingga titik panggilan ke fork ().

Jika panggilan ke fork () berhasil dijalankan, Unix akan membuat dua salinan identik dari ruang alamat, satu untuk induk dan yang lainnya untuk anak. Kedua proses akan memulai eksekusinya pada pernyataan berikutnya setelah panggilan fork (). Dalam hal ini, kedua proses akan memulai pelaksanaannya di penugasan

Kedua proses memulai eksekusinya tepat setelah system call fork (). Karena kedua proses memiliki ruang alamat yang identik tetapi terpisah, variabel-variabel yang diinisialisasi sebelum panggilan fork () memiliki nilai yang sama di kedua ruang alamat. Karena setiap proses memiliki ruang alamatnya sendiri, modifikasi apa pun akan independen dari yang lain. Dengan kata lain, jika induk mengubah nilai variabelnya, modifikasi hanya akan mempengaruhi variabel dalam ruang alamat proses induk. Ruang alamat lain yang dibuat oleh panggilan fork () tidak akan terpengaruh meskipun mereka memiliki nama variabel yang identik.

Apa alasan menggunakan tulis daripada printf? Itu karena printf () adalah "buffered", yang berarti printf () akan mengelompokkan output dari suatu proses bersama-sama. Saat melakukan buffering output untuk proses induk, anak juga dapat menggunakan printf untuk mencetak beberapa informasi, yang juga akan di-buffer. Akibatnya, karena keluaran tidak akan langsung dikirim ke layar, Anda mungkin tidak mendapatkan urutan yang benar dari hasil yang diharapkan. Lebih buruk lagi, keluaran dari kedua proses tersebut mungkin tercampur dengan cara yang aneh. Untuk mengatasi masalah ini, Anda dapat mempertimbangkan untuk menggunakan tulisan "unbuffered".

Jika Anda menjalankan program ini, Anda mungkin melihat yang berikut ini di layar:

ID Proses 3456 mungkin yang ditetapkan ke orang tua atau anak. Karena fakta bahwa proses ini dijalankan secara bersamaan, jalur keluarannya bercampur dengan cara yang agak tidak terduga. Selain itu, urutan baris ini ditentukan oleh penjadwal CPU. Karenanya, jika Anda menjalankan program ini lagi, Anda mungkin mendapatkan hasil yang sama sekali berbeda.

cpp-coder
sumber
4
Alih-alih menyalin-menempel teks, Anda dapat mengomentari tautan: csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html
chaitanya lakkundi
3

Multiprocessing adalah pusat komputasi. Misalnya, IE atau Firefox Anda dapat membuat proses untuk mengunduh file untuk Anda saat Anda masih menjelajah internet. Atau, saat Anda mencetak dokumen dalam pengolah kata, Anda masih dapat melihat halaman yang berbeda dan masih melakukan beberapa pengeditan dengannya.

nonopolaritas
sumber
3

Fork () digunakan untuk membuat proses baru seperti yang telah ditulis oleh setiap tubuh.

Berikut adalah kode saya yang membuat proses dalam bentuk pohon biner ....... Ini akan meminta untuk memindai jumlah level yang Anda inginkan untuk membuat proses dalam pohon biner.

KELUARAN

Anil Kumar Arya
sumber
2

Pertama, orang perlu memahami apa itu pemanggilan sistem fork (). Biar saya jelaskan

  1. panggilan sistem fork () membuat duplikat yang tepat dari proses induk, itu membuat duplikat tumpukan induk, heap, data yang diinisialisasi, data yang tidak diinisialisasi dan berbagi kode dalam mode hanya-baca dengan proses induk.

  2. Panggilan sistem garpu menyalin memori pada basis copy-on-write, berarti anak membuat di halaman memori virtual ketika ada persyaratan penyalinan.

Sekarang Tujuan dari fork ():

  1. Fork () bisa digunakan di tempat dimana ada pembagian pekerjaan seperti server harus menangani banyak klien, Jadi induk harus menerima koneksi secara teratur, Jadi server melakukan fork untuk setiap klien untuk melakukan baca-tulis.
Sandeep_black
sumber
1

fork()digunakan untuk menelurkan proses anak. Biasanya ini digunakan dalam situasi yang sama seperti threading, tetapi ada perbedaan. Tidak seperti utas, fork()menciptakan seluruh proses terpisah, yang berarti bahwa anak dan orang tua sementara mereka adalah salinan langsung satu sama lain pada titik yang fork()dipanggil, mereka benar-benar terpisah, tidak ada yang dapat mengakses ruang memori orang lain (tanpa pergi ke masalah normal Anda pergi untuk mengakses memori program lain).

fork()masih digunakan oleh beberapa aplikasi server, kebanyakan yang berjalan sebagai root pada mesin * NIX yang melepaskan izin sebelum memproses permintaan pengguna. Masih ada beberapa kasus penggunaan lain, tetapi kebanyakan orang telah pindah ke multithreading sekarang.

Matthew Scharley
sumber
2
Saya tidak memahami persepsi bahwa "kebanyakan orang" telah pindah ke multithreading. Prosesnya akan tetap ada, begitu juga utasnya. Tidak ada yang "pindah" dari keduanya. Dalam pemrograman paralel, kode terbesar dan paling bersamaan adalah program multi-proses memori terdistribusi (misalnya MapReduce dan MPI). Namun, kebanyakan orang akan memilih OpenMP atau beberapa paradigma memori bersama untuk mesin multicore, dan GPU menggunakan utas hari ini, tetapi ada banyak hal di luar itu. Saya yakin, bagaimanapun, bahwa lebih banyak pembuat kode di situs ini mengalami paralelisme proses di sisi server daripada apa pun yang multithread.
Todd Gamblin
1

Alasan di balik fork () versus hanya memiliki fungsi exec () untuk memulai proses baru dijelaskan dalam jawaban untuk pertanyaan serupa pada pertukaran tumpukan unix .

Pada dasarnya, karena fork menyalin proses saat ini, semua opsi yang memungkinkan untuk suatu proses ditetapkan secara default, sehingga programmer tidak menyediakannya.

Dalam sistem operasi Windows, sebaliknya, programmer harus menggunakan fungsi CreateProcess yang JAUH lebih rumit dan membutuhkan struktur beraneka ragam untuk menentukan parameter dari proses baru.

Jadi, singkatnya, alasan forking (versus exec'ing) adalah kesederhanaan dalam membuat proses baru.

Tyler Durden
sumber
0

Pemanggilan sistem Fork () digunakan untuk membuat proses anak. Ini adalah duplikat persis dari proses induk. Bagian tumpukan salinan garpu, bagian heap, bagian data, variabel lingkungan, argumen baris perintah dari induk.

lihat: http://man7.org/linux/man-pages/man2/fork.2.html


sumber
0

Fungsi fork () digunakan untuk membuat proses baru dengan menduplikasi proses yang ada dari mana ia dipanggil. Proses yang ada di mana fungsi ini dipanggil menjadi proses induk dan proses yang baru dibuat menjadi proses anak. Seperti yang telah dinyatakan bahwa anak adalah salinan duplikat dari induknya tetapi ada beberapa pengecualian untuk itu.

  • Anak tersebut memiliki PID unik seperti proses lain yang berjalan di sistem operasi.

  • Anak tersebut memiliki ID proses induk yang sama dengan PID dari
    proses yang membuatnya.

  • Pemanfaatan sumber daya dan penghitung waktu CPU disetel ulang ke nol dalam proses anak.

  • Set sinyal tertunda pada anak kosong.

  • Anak tidak mewarisi timer apa pun dari orang tuanya

Contoh:

Sekarang, ketika kode di atas dikompilasi dan dijalankan:

Usman
sumber