Threads vs (Forked) Proses


9

Aplikasi Linux umumnya bercabang kemudian exec (with execve ()), tetapi aplikasi Java, dan Apache MPM tertentu menggunakan threading. Jika forking, gunakan fork + exec untuk menelurkan sebuah proses, apa versi tingkat tinggi untuk threading? Bagaimana JVM atau Worker MPM menelurkan utas?


2
Lihat Stackoverflow. Ada beberapa T&J di sana yang telah menjelaskan bagian dari ini.
Henk Langeveld

Jawaban:


13

Gagasan di balik utas dan proses hampir sama: Anda bercabang di jalur eksekusi. Kalau tidak, utas dan proses berbeda dalam hal-hal seperti memori. Yaitu proses memiliki ruang VM yang berbeda sementara utas berbagi apa pun yang ada sebelum pemisahan.

Mendasari pekerjaan threading dan forking dengan menggunakan panggilan clone () (man 2 clone):

Tidak seperti fork (2), clone () memungkinkan proses anak untuk berbagi bagian dari konteks eksekusi dengan proses panggilan, seperti ruang memori, tabel deskriptor file, dan tabel penangan sinyal. (Perhatikan bahwa pada halaman manual ini, "proses panggilan" biasanya sesuai dengan "proses induk". Tetapi lihat deskripsi CLONE_PARENT di bawah ini.)

Penggunaan utama clone () adalah untuk mengimplementasikan utas: beberapa utas kontrol dalam program yang berjalan bersamaan di ruang memori bersama.

Perbedaan datang dari bendera yang diberikan untuk mengkloning (). Seperti yang Anda lihat dari halaman manual, fork dan threading hanyalah satu set parameter yang telah ditentukan untuk dikloning (). Namun seseorang juga dapat melakukan hal-hal khusus dengannya.


1
Uhm? Apa? Harap baca kembali hampir setiap buku tentang topik ini, karena ruang memori terpisah untuk proses adalah masalah besar. Juga membantu "menangkap" kode yang macet, sedangkan kernel hanya akan membunuh proses di mana masing-masing utas menjadi rusak.
0xC0000022L

3
@ 0xC0000022L argumen Anda tidak bertentangan dengan jawabannya, menurut saya.
Ruslan

1
@Ruslan: Saya mohon berbeda: "Idenya [...] hampir sama"? Gagasan di balik utas memang konkurensi, tetapi untuk proses ini adalah cerita yang sama sekali berbeda.
0xC0000022L

4
@ 0xC0000022L Anda melewatkan bagian penting dari jawaban V13: "Anda bercabang di jalur eksekusi" - pertanyaannya adalah tentang bagaimana utas muncul, bukan apa perbedaan antara utas dan prosesnya
Izkata

@Izkata: tidak sama sekali. Saya hanya berpendapat bahwa ini bukan klaim yang benar.
0xC0000022L

8

Kebanyakan sistem operasi multiprosesing non-Unix (OS) menggunakan panggilan "spawn ()" atau sesuatu yang serupa untuk menghasilkan proses OS baru atau aliran kontrol. Spawn () cenderung menjadi panggilan yang sangat kompleks, dengan banyak opsi dan banyak overhead. Salah satu inovasi Unix adalah menyediakan cara overhead yang jauh lebih rendah untuk menciptakan proses - fork (). Unix menangani banyak opsi yang diperlukan untuk menelurkan () dengan mengizinkan jumlah pemrosesan sewenang-wenang sebelum separuh lainnya bertelur (), dengan exec ().

Karena Unix dan varian-varian daripadanya semakin banyak digunakan, pembuatan proses overhead yang rendah ternyata bermanfaat, dan digunakan. Bahkan, itu digunakan begitu banyak, sehingga orang ingin cara overhead yang lebih rendah untuk membuat proses, dan ide "utas" lahir. Awalnya, utas ditangani sepenuhnya oleh proses asalnya (dan program seperti JVM dapat melakukan ini dengan "utas hijau"); tetapi menangani penjadwalan multi-thread sulit dan sering dilakukan secara tidak benar. Jadi ada cara yang lebih mudah, menengah untuk melakukan utas, di mana OS menangani penjadwalan tetapi beberapa overhead disimpan oleh (biasanya) berbagi ruang alamat antar utas.

Pertanyaan Anda sulit dijawab karena ada beberapa konsep berbeda tetapi terkait yang semuanya "utas," dan untuk detail Anda perlu kata sifat untuk menggambarkan mana yang Anda rujuk. Di sisi lain, memahami perbedaan mungkin akan mengarahkan Anda ke jawaban spesifik yang Anda inginkan. Cari hal-hal seperti "proses ringan," "utas pengguna," dan "rfork ()" untuk info lebih lanjut.


1
"Menangani penjadwalan multi-thread itu rumit dan sering dilakukan secara tidak tepat" kutipan diperlukan. Menerapkan utas ruang pengguna bukan masalah. Masalah dengan utas ruang pengguna adalah bahwa jika utas melakukan pemblokiran syscall, semua utas diblokir. Satu-satunya cara untuk menghindari ini adalah dengan menggunakan utas level sistem.
Bakuriu

1
Menariknya, Windows tidak memasukkan inovasi Unix ini: ia memiliki CreateProcess()tetapi tidak ada yang serupa fork().
Ruslan

2
@ Bakuriu - lihat banyak artikel tentang membangun penjadwal multiprosesing, menjaga keadilan, menghindari kelaparan, menangani prioritas, dll. Menerapkan utas ruang pengguna bukan, seperti yang Anda katakan masalah. Penjadwalan contoh non-sepele sulit.
mpez0

@Ruslan: satu dapat bercabang pada Windows, itu hanya bukan bagian dari Win32 API. Baca "API Asli Windows NT / 2000" oleh Nebbett. Dia memiliki implementasi yang meniru fork().
0xC0000022L

3

Thread dan forking sebenarnya adalah dua konsep yang berbeda, keduanya ada dalam sistem Unix / Linux (dan keduanya dapat digunakan dalam C / C ++).

Gagasan fork () pada dasarnya adalah penciptaan proses terpisah yang memiliki kode eksekusi yang sama dengan proses induk, dan yang memulai eksekusi pada baris fork. Tujuan menggunakan garpu dengan fungsi exec adalah bahwa fungsi exec menutup proses yang memanggil mereka ketika mereka berakhir. Jadi, Anda biasanya bercabang, mendapatkan PID dari setiap proses (anak selalu 0), dan membuat orang tua menunggu sampai anak selesai menjalankan fungsi exec.

Thread digunakan untuk paralelisme (ingat bahwa orang tua menunggu anak, biasanya, dalam program bercabang). Utas, seperti pthread dalam C / C ++ (melakukan pencarian Google), akan berjalan secara paralel dengan proses utama, dan dapat berbagi variabel global dan fungsi global dengan program asli. Karena thread Java berperilaku serupa, saya akan membayangkan bahwa mereka bertindak lebih seperti thread ini daripada seperti proses forking.

Pada dasarnya, ada perbedaan antara forking dan threading. Mereka melakukan hal-hal yang sangat berbeda (walaupun tampak serupa). Konsep-konsep ini mungkin sulit dipahami, tetapi Anda dapat mempelajarinya melalui penelitian (luas) jika Anda memiliki keinginan yang jujur ​​untuk memahaminya.

EDIT # 1

Silakan lihat contoh-contoh ini bagaimana garpu dan utas dapat dipanggil dan digunakan. Harap perhatikan perilaku fungsi exec dan efeknya pada program utama.

http://www.jdembrun.com:4352/computerScience/forkVSthread.zip


2
Fork (dengan atau tanpa exec) dapat digunakan untuk paralelisme juga. Saya tidak yakin apa yang Anda maksud dengan "fungsi exec menutup proses yang memanggil mereka ketika mereka berakhir", exec sudah lama selesai berjalan ketika proses berakhir. Juga pthreadmerupakan API, bukan implementasi utas.
Mat

Pada hal garpu, saya mengutip guru OS saya. Menurut apa yang dia katakan kepada kita, ya, forking dapat digunakan untuk berjalan secara paralel, tetapi, jika menggunakan fungsi exec, itu akan menjadi yang terakhir. Adapun pthread, itu dimaksudkan sebagai contoh.
jaredad7

Exec akan menjadi panggilan terakhir dalam kode pemanggil, bukan instruksi terakhir proses bercabang itu. Proses bercabang akan hidup menjalankan kode eksekutif.
Mat

Komentar Anda telah mendorong saya untuk menguji hal-hal ini. Saya telah menulis beberapa program c ++ yang menunjukkan perilaku fungsi exec dan efeknya pada program ketika digunakan dalam fork vs. thread. Silakan lihat hasil edit di atas.
jaredad7

Saya khawatir kebanyakan orang tidak akan repot-repot mengunduh itu. Contoh Anda juga tidak menggambarkan perbedaan menarik antara model, yang sebagian besar terkait dengan berbagi (atau tidak) ruang alamat.
Mat

1

Baik JVM dan Apache MPM mengandalkan kernel untuk utas asli. Artinya, mereka menggunakan OS untuk menjadwalkannya. Tentu saja keduanya membutuhkan API mereka sendiri untuk melacak hal-hal.

Stackoverflow sudah memiliki beberapa pertanyaan yang berhubungan dengan ini:

  1. JVM utas asli , lihat jawaban ini untuk lebih detail.

  2. Apache memiliki dua jenis MPM: Prefork, dengan satu proses per utas, dan Pekerja, yang menangani beberapa utas: Apache MPM . Lihatlah referensi untukcodebucket


1

Jika forking, gunakan fork + exec untuk menelurkan sebuah proses, apa versi tingkat tinggi untuk threading? Bagaimana JVM atau Worker MPM menelurkan utas?

Itu adalah platform khusus, tetapi di linux dan saya akan menganggap banyak sistem lain yang sesuai dengan POSIX mereka menggunakan implementasi lokal pthreads , sebuah API threading userland. Misalnya:

#include <pthread.h>

pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);

Mulai utas panggilan baru somefuncsebagai titik eksekusi pertama.

Anda juga dapat membuat utas - berbeda dari garpu karena mereka berbagi ruang memori tumpukan global yang sama dari proses induk, alih-alih mendapatkan salinan duplikatnya (tetapi utas catatan masing-masing dijalankan dengan memori tumpukan independen sendiri) - dengan clone()panggilan sistem, yang merupakan pthreads yang dibangun di atas.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.