Apa perbedaan antara proses dan utas?


1641

Apa perbedaan teknis antara proses dan utas?

Saya merasa kata 'proses' terlalu sering digunakan dan ada juga perangkat keras dan utas perangkat lunak. Bagaimana dengan proses ringan dalam bahasa seperti Erlang ? Apakah ada alasan pasti untuk menggunakan satu istilah di atas yang lain?



4
Mungkin waran mengatakan bahwa setiap OS memiliki ide yang berbeda tentang apa yang merupakan 'utas' atau 'proses'. Beberapa OS arus utama 'tidak memiliki konsep' utas ', ada juga beberapa OS yang disematkan' yang hanya memiliki 'utas'.
Neil

Jawaban:


1459

Baik proses dan utas merupakan urutan eksekusi yang independen. Perbedaan khasnya adalah bahwa utas (dari proses yang sama) berjalan dalam ruang memori bersama, sementara proses dijalankan dalam ruang memori yang terpisah.

Saya tidak yakin apa utas "perangkat keras" vs "perangkat lunak" yang Anda maksud. Thread adalah fitur lingkungan operasi, bukan fitur CPU (meskipun CPU biasanya memiliki operasi yang membuat thread lebih efisien).

Erlang menggunakan istilah "proses" karena tidak mengekspos model multiprogramming-memori bersama. Menyebutnya "utas" akan menyiratkan bahwa mereka telah berbagi memori.


56
Utas perangkat keras mungkin merujuk ke beberapa konteks utas dalam sebuah inti (mis. HyperThreading, SMT, Sun's Niagara / Rock). Ini berarti file register duplikat, bit ekstra yang dibawa-bawa dengan instruksi melalui jalur pipa, dan logika bypassing / forwarding yang lebih kompleks, antara lain.
Matt J

4
@reg, satu keraguan yang saya miliki di utas. biarkan saya mempertimbangkan saya memiliki proses A, yang mendapat beberapa ruang dalam RAM. Jika proses A membuat utas, utas juga membutuhkan ruang untuk dijalankan. Jadi apakah akan menambah ukuran ruang yang dibuat untuk proses A, atau ruang untuk utas yang dibuat di tempat lain? jadi apa yang proses ruang virtual ciptakan? Harap perbaiki saya jika pertanyaan saya salah. Terima kasih
duslabo

9
@JeshwanthKumarNK: Membuat utas baru mengalokasikan setidaknya memori yang cukup untuk tumpukan baru. Memori ini dialokasikan oleh OS dalam proses A.
Greg Hewgill

24
Jawaban ini sepertinya salah. Jika kedua proses dan utas merupakan urutan eksekusi yang independen, maka proses yang berisi dua utas harus memiliki tiga urutan eksekusi, dan itu tidak mungkin benar. Hanya utas yang merupakan urutan eksekusi - suatu proses adalah wadah yang dapat menampung satu atau lebih urutan eksekusi.
David Schwartz

8
"Utas perangkat keras" adalah utas yang diberi sumber daya perangkat keras individual (inti, prosesor, atau Hyperhread terpisah). "Utas perangkat lunak" adalah utas yang harus bersaing untuk mendapatkan kekuatan pemrosesan yang sama.
jpmc26

811

Proses
Setiap proses menyediakan sumber daya yang diperlukan untuk menjalankan suatu program. Suatu proses memiliki ruang alamat virtual, kode yang dapat dieksekusi, pegangan terbuka ke objek sistem, konteks keamanan, pengidentifikasi proses yang unik, variabel lingkungan, kelas prioritas, ukuran set kerja minimum dan maksimum, dan setidaknya satu utas eksekusi. Setiap proses dimulai dengan utas tunggal, sering disebut utas primer, tetapi dapat membuat utas tambahan dari salah satu utasnya.

Utas
Utas adalah entitas dalam proses yang dapat dijadwalkan untuk dieksekusi. Semua utas proses berbagi ruang alamat virtual dan sumber daya sistem. Selain itu, setiap utas mempertahankan penangan pengecualian, prioritas penjadwalan, penyimpanan lokal utas, pengenal utas unik, dan seperangkat struktur yang akan digunakan sistem untuk menyimpan konteks utas sampai dijadwalkan. Konteks thread termasuk set thread register mesin, tumpukan kernel, blok lingkungan thread, dan tumpukan pengguna di ruang alamat dari proses thread. Utas juga dapat memiliki konteks keamanannya sendiri, yang dapat digunakan untuk menyamar sebagai klien.


Informasi ini ditemukan di Microsoft Documents di sini: Tentang Proses dan Utas

Microsoft Windows mendukung preemptive multitasking, yang menciptakan efek eksekusi simultan beberapa utas dari berbagai proses. Pada komputer multiprosesor, sistem secara bersamaan dapat mengeksekusi thread sebanyak yang ada pada prosesor pada komputer.


18
Untuk orang-orang yang ingin tahu mengapa Anda tidak dapat memformat disket pada saat yang bersamaan: stackoverflow.com/questions/20708707/…
Computernerd

7
@LuisVasconcellos - Jika tidak ada utas, maka prosesnya tidak akan melakukan apa-apa. Prosesnya hanya akan berupa beberapa kode dan status program yang dimuat ke dalam memori. Tidak banyak gunanya. Itu seperti memiliki jalan tanpa kendaraan yang melaju di sana.
Scott Langham

4
@LuisVasconcellos - Bagus. Ya, Anda dapat menganggap utas sebagai sesuatu yang bergerak melalui kode proses dan yang menjalankan instruksi dalam kode itu.
Scott Langham

9
Jawaban ini jauh lebih baik daripada jawaban yang diterima karena ini berbicara tentang ideal dari proses dan utas: Mereka harus memisahkan hal-hal dengan masalah yang berbeda. Faktanya adalah, sebagian besar sistem operasi memiliki sejarah yang kembali lebih jauh dari penemuan benang, dan akibatnya, di sebagian besar sistem operasi, kekhawatiran itu masih agak terjerat, bahkan jika mereka perlahan-lahan membaik seiring waktu.
Solomon Slow

4
@ BKSpurgeon Dengan setiap penjelasan yang diberikan, Anda harus membawa pembaca dari satu tingkat pemahaman ke tingkat berikutnya. Sayangnya, saya tidak dapat menyesuaikan jawaban untuk setiap pembaca dan karenanya harus mengasumsikan tingkat pengetahuan. Bagi mereka yang tidak tahu, mereka dapat melakukan pencarian lebih lanjut dari istilah yang saya gunakan, mereka tidak mengerti, tidak bisa, sampai mereka mencapai titik dasar yang mereka mengerti. Saya akan menyarankan Anda menawarkan jawaban Anda sendiri, tetapi saya senang melihat Anda sudah memilikinya.
Scott Langham

301

Proses:

  • Instansi pelaksana program disebut proses.
  • Beberapa sistem operasi menggunakan istilah 'tugas' untuk merujuk ke program yang sedang dijalankan.
  • Suatu proses yang selalu disimpan dalam memori utama juga disebut sebagai memori primer atau memori akses acak.
  • Oleh karena itu, suatu proses disebut sebagai entitas aktif. Hilang jika mesin reboot.
  • Beberapa proses dapat dikaitkan dengan program yang sama.
  • Pada sistem multiprosesor, banyak proses dapat dieksekusi secara paralel.
  • Pada sistem uni-prosesor, meskipun paralelisme sejati tidak tercapai, algoritma penjadwalan proses diterapkan dan prosesor dijadwalkan untuk mengeksekusi setiap proses satu per satu menghasilkan ilusi konkurensi.
  • Contoh: Menjalankan beberapa instance dari program 'Kalkulator'. Masing-masing contoh disebut sebagai suatu proses.

Benang:

  • Thread adalah bagian dari proses.
  • Ini disebut sebagai 'proses ringan', karena mirip dengan proses nyata tetapi dieksekusi dalam konteks suatu proses dan berbagi sumber daya yang sama yang dialokasikan untuk proses oleh kernel.
  • Biasanya, suatu proses hanya memiliki satu utas kontrol - satu set instruksi mesin yang dijalankan pada satu waktu.
  • Suatu proses dapat juga terdiri dari beberapa utas eksekusi yang mengeksekusi instruksi secara bersamaan.
  • Beberapa utas kontrol dapat mengeksploitasi paralelisme sebenarnya yang dimungkinkan pada sistem multiprosesor.
  • Pada sistem uni-prosesor, algoritma penjadwalan thread diterapkan dan prosesor dijadwalkan untuk menjalankan setiap utas pada satu waktu.
  • Semua utas yang berjalan dalam suatu proses berbagi ruang alamat yang sama, deskriptor file, tumpukan, dan atribut terkait proses lainnya.
  • Karena utas proses berbagi memori yang sama, menyinkronkan akses ke data yang dibagikan dalam proses mendapatkan kepentingan yang belum pernah terjadi sebelumnya.

Saya meminjam info di atas dari Knowledge Quest! blog .


90
Kumar: Dari sepengetahuan saya, utas tidak berbagi tumpukan yang sama. Kalau tidak, tidak mungkin menjalankan kode yang berbeda pada masing-masing kode.
Mihai Neacsu

27
Yup, saya pikir @MihaiNeacsu benar. Thread berbagi "kode, data, dan file" dan memiliki "register and stack" sendiri. Slide dari kursus OS saya: i.imgur.com/Iq1Qprv.png
Shehaaz

Ini cukup berguna, karena memperluas tentang apa benang dan proses dan bagaimana mereka saling berhubungan. Saya sarankan menambahkan contoh Thread, terutama karena ada satu untuk Proses. Barang bagus!
Smithers

1
Tautan Kquest.co.cc sudah mati.
Elijah Lynn

1
@ Rndp13 Masalahnya hanyalah penggunaan kata "tumpukan" daripada "tumpukan". Thread tidak berbagi tumpukan karena stack hanya sebagian dari memori virtual dan thread berbagi semua memori virtual. Thread bahkan dapat menyimpan stack pointer mereka dan eksekusi dapat dilanjutkan oleh utas lain tanpa masalah. Bahwa satu utas kebetulan mengeksekusi satu tumpukan pada satu waktu tertentu tidak berarti utas tidak berbagi tumpukan seperti fakta bahwa satu utas beroperasi pada deskriptor file pada satu waktu tidak berarti utas tidak berbagi deskriptor file .
David Schwartz

129

Pertama, mari kita lihat aspek teoretisnya. Anda perlu memahami apa proses secara konseptual untuk memahami perbedaan antara proses dan utas dan apa yang dibagikan di antara mereka.

Kami memiliki yang berikut dari bagian 2.2.2 Model Thread Klasik dalam Sistem Operasi Modern 3e oleh Tanenbaum:

Model proses didasarkan pada dua konsep independen: pengelompokan sumber daya dan eksekusi. Terkadang berguna untuk memisahkan mereka; Di sinilah utas masuk ....

Dia melanjutkan:

Salah satu cara memandang suatu proses adalah cara mengelompokkan sumber daya terkait. Suatu proses memiliki ruang alamat yang berisi teks dan data program, serta sumber daya lainnya. Sumber daya ini dapat mencakup file terbuka, proses anak, alarm yang tertunda, penangan sinyal, informasi akuntansi, dan banyak lagi. Dengan menyatukan mereka dalam bentuk proses, mereka dapat dikelola dengan lebih mudah. Konsep lain yang dimiliki suatu proses adalah utas eksekusi, biasanya disingkat menjadi hanya utas. Utas memiliki penghitung program yang melacak instruksi mana yang harus dijalankan selanjutnya. Ini memiliki register, yang menyimpan variabel kerja saat ini. Ini memiliki tumpukan, yang berisi riwayat eksekusi, dengan satu frame untuk setiap prosedur yang dipanggil tetapi belum kembali dari. Meskipun utas harus dijalankan dalam beberapa proses, utas dan prosesnya adalah konsep yang berbeda dan dapat diperlakukan secara terpisah. Proses digunakan untuk mengelompokkan sumber daya bersama; utas adalah entitas yang dijadwalkan untuk dieksekusi pada CPU.

Lebih jauh ke bawah ia menyediakan tabel berikut:

Per process items             | Per thread items
------------------------------|-----------------
Address space                 | Program counter
Global variables              | Registers
Open files                    | Stack
Child processes               | State
Pending alarms                |
Signals and signal handlers   |
Accounting information        |

Mari kita berurusan dengan masalah multithreading perangkat keras . Secara klasik, CPU akan mendukung satu utas eksekusi, mempertahankan status utas melalui penghitung program tunggal, dan serangkaian register. Tetapi apa yang terjadi jika ada cache yang hilang? Butuh waktu lama untuk mengambil data dari memori utama, dan sementara itu terjadi CPU hanya duduk diam di sana. Jadi seseorang memiliki ide untuk pada dasarnya memiliki dua set status utas (register + PC) sehingga utas lain (mungkin dalam proses yang sama, mungkin dalam proses yang berbeda) dapat menyelesaikan pekerjaan sementara utas lainnya menunggu di memori utama. Ada beberapa nama dan implementasi dari konsep ini, seperti HyperThreading dan Simultaneous Multithreading ( disingkat SMT).

Sekarang mari kita lihat sisi perangkat lunaknya. Pada dasarnya ada tiga cara agar thread dapat diterapkan pada sisi perangkat lunak.

  1. Userpace Threads
  2. Kernel Threads
  3. Kombinasi keduanya

Yang Anda butuhkan untuk mengimplementasikan thread adalah kemampuan untuk menyimpan status CPU dan memelihara banyak tumpukan, yang dalam banyak kasus dapat dilakukan di ruang pengguna. Keuntungan dari thread ruang pengguna adalah peralihan thread super cepat karena Anda tidak perlu menjebak ke dalam kernel dan kemampuan untuk menjadwalkan thread Anda seperti yang Anda suka. Kelemahan terbesar adalah ketidakmampuan untuk melakukan pemblokiran I / O (yang akan memblokir seluruh proses dan semua utas pengguna), yang merupakan salah satu alasan utama kami menggunakan utas di tempat pertama. Memblokir I / O menggunakan utas sangat menyederhanakan desain program dalam banyak kasus.

Utas kernel memiliki keunggulan karena dapat menggunakan pemblokiran I / O, selain meninggalkan semua masalah penjadwalan ke OS. Tetapi setiap switch thread memerlukan trapping ke dalam kernel yang berpotensi relatif lambat. Namun, jika Anda mengganti utas karena diblokir I / O ini bukan masalah karena operasi I / O mungkin sudah menjebak Anda ke dalam kernel.

Pendekatan lain adalah menggabungkan keduanya, dengan beberapa utas kernel yang masing-masing memiliki beberapa utas pengguna.

Jadi kembali ke pertanyaan Anda tentang terminologi, Anda dapat melihat bahwa suatu proses dan untaian eksekusi adalah dua konsep yang berbeda dan pilihan Anda untuk istilah mana yang akan digunakan tergantung pada apa yang Anda bicarakan. Mengenai istilah "proses berat ringan", saya pribadi tidak melihat maksud di dalamnya karena tidak benar-benar menyampaikan apa yang terjadi serta istilah "utas eksekusi".


4
Jawaban yang luar biasa! Ini memecah banyak jargon dan asumsi. Namun, hal ini membuat garis ini tampak canggung: "Jadi seseorang memiliki ide untuk memiliki dua set status utas (register + PC)" - apa "PC" yang dimaksud di sini?
Smithers

2
@Smithers PC adalah penghitung program, atau penunjuk instruksi, yang memberikan alamat instruksi selanjutnya yang akan dieksekusi: en.wikipedia.org/wiki/Program_counter
Robert S. Barnes


Mengapa "Stack" tidak terdaftar di bawah "Per item proses"? Baik proses dan utas memiliki tumpukan sendiri.
stackoverflowuser2010

1
@ stackoverflowuser2010 tidak hanya utas yang memiliki tumpukan. Apa yang Anda sebut proses adalah proses dengan satu utas eksekusi dan itu adalah utas yang memiliki tumpukan bukan proses.
Robert S. Barnes

101

Untuk menjelaskan lebih banyak sehubungan dengan pemrograman bersamaan

  1. Suatu proses memiliki lingkungan eksekusi mandiri. Suatu proses umumnya memiliki set lengkap, sumber daya run-time dasar pribadi; khususnya, setiap proses memiliki ruang memori sendiri.

  2. Thread ada dalam suatu proses - setiap proses memiliki setidaknya satu. Utas membagikan sumber daya proses, termasuk memori dan file yang terbuka. Ini membuat komunikasi menjadi efisien, tetapi berpotensi bermasalah.

Mempertahankan orang biasa dalam pikiran,

Di komputer Anda, buka Microsoft Word dan browser web. Kami menyebut dua proses ini .

Di Microsoft word, Anda mengetik sesuatu dan secara otomatis disimpan. Sekarang, Anda akan mengamati pengeditan dan penyimpanan terjadi secara paralel - pengeditan pada satu utas dan penghematan pada utas lainnya.


14
Jawaban yang luar biasa, itu membuat hal-hal sederhana dan memberikan contoh setiap pengguna bahkan melihat pertanyaan yang berhubungan.
Smithers

7
mengedit / menyimpan adalah contoh yang bagus untuk banyak utas di dalam suatu proses!

53

Aplikasi terdiri dari satu proses atau lebih. Suatu proses, dalam istilah yang paling sederhana, adalah program pelaksana. Satu atau lebih utas berjalan dalam konteks proses. Utas adalah unit dasar yang digunakan sistem operasi untuk mengalokasikan waktu prosesor. Sebuah utas dapat mengeksekusi bagian mana pun dari kode proses, termasuk bagian yang saat ini dieksekusi oleh utas lain. Serat adalah unit eksekusi yang harus dijadwalkan secara manual oleh aplikasi. Serat berjalan dalam konteks utas yang menjadwalkannya.

Dicuri dari sini .


Pada sistem operasi lain, seperti Linux, tidak ada perbedaan praktis antara keduanya di tingkat sistem operasi, kecuali bahwa utas biasanya berbagi ruang memori yang sama dengan proses induk. (Karenanya downvote saya)
Arafangion

1
Jawaban yang baik (terutama dengan kredit), karena menunjukkan hubungan antara keduanya dan segues menjadi "pertanyaan selanjutnya" yang mudah diharapkan (tentang serat).
Smithers

29

Suatu proses adalah kumpulan kode, memori, data dan sumber daya lainnya. Utas adalah urutan kode yang dieksekusi dalam lingkup proses. Anda dapat (biasanya) memiliki beberapa utas yang berjalan bersamaan dalam proses yang sama.


27

Contoh dunia nyata untuk Proses dan Utas Ini akan memberi Anda ide dasar tentang utas dan proses masukkan deskripsi gambar di sini

Saya meminjam info di atas dari Jawaban Scott Langham - terima kasih


25

Proses:

  1. Proses adalah proses yang berat.
  2. Proses adalah program terpisah yang memiliki memori terpisah, data, sumber daya dll.
  3. Proses dibuat menggunakan metode fork ().
  4. Pergantian konteks antara proses ini memakan waktu.

Contoh:
Katakan, buka browser apa saja (mozilla, Chrome, IE). Pada titik ini proses baru akan mulai dijalankan.

Utas:

  1. Thread adalah proses yang ringan. Benang dibundel di dalam proses.
  2. Utas memiliki memori, data, sumber daya, file bersama, dll.
  3. Utas dibuat menggunakan metode clone ().
  4. Pergantian konteks antara utas tidak memakan banyak waktu sebagai Proses.

Contoh:
Membuka banyak tab di browser.


Di dunia Windows Anda benar, tetapi di Linux setiap 'utas' adalah sebuah proses dan sama-sama 'berat' (atau ringan).
Neil

22
  • Setiap proses adalah utas (utas utama).
  • Tetapi setiap utas bukanlah proses. Ini adalah bagian (entitas) dari suatu proses.

3
Bisakah Anda menjelaskannya sedikit lebih jauh dan / atau menyertakan beberapa bukti?
Zim84

15

Baik utas maupun proses adalah unit atom alokasi sumber daya OS (yaitu ada model konkurensi yang menggambarkan bagaimana waktu CPU dibagi di antara mereka, dan model kepemilikan sumber daya OS lainnya). Ada perbedaan dalam:

  • Sumber daya bersama (utas berbagi memori berdasarkan definisi, mereka tidak memiliki apa pun kecuali tumpukan dan variabel lokal; proses juga dapat berbagi memori, tetapi ada mekanisme terpisah untuk itu, dikelola oleh OS)
  • Ruang alokasi (ruang kernel untuk proses vs. ruang pengguna untuk utas)

Greg Hewgill di atas benar tentang arti Erlang dari kata "proses", dan di sini ada diskusi mengapa Erlang bisa melakukan proses yang ringan.


13

Baik proses dan utas merupakan urutan eksekusi yang independen. Perbedaan khasnya adalah bahwa utas (dari proses yang sama) berjalan dalam ruang memori bersama, sementara proses dijalankan dalam ruang memori yang terpisah.

Proses

Merupakan program yang sedang dieksekusi. memiliki bagian teks yaitu kode program, aktivitas saat ini seperti yang diwakili oleh nilai program counter & konten register prosesor. Ini juga termasuk tumpukan proses yang berisi data sementara (seperti parameter fungsi, variabel yang dialamatkan kembali dan lokal), dan bagian data, yang berisi variabel global. Suatu proses juga dapat mencakup heap, yang merupakan memori yang dialokasikan secara dinamis selama waktu proses berjalan.

Benang

Utas adalah unit dasar pemanfaatan CPU; terdiri dari ID utas, penghitung program, set register, dan setumpuk. itu berbagi dengan utas lain yang memiliki proses yang sama bagian kodenya, bagian data dan sumber daya sistem operasi lainnya seperti file dan sinyal terbuka.

- Diambil dari Sistem Operasi oleh Galvin


13

http://lkml.iu.edu/hypermail/linux/kernel/9608/0191.html

Linus Torvalds (torvalds@cs.helsinki.fi)

Sel, 6 Agustus 1996 12:47:31 +300 (EET DST)

Pesan diurutkan berdasarkan: [tanggal] [utas] [subjek] [penulis]

Pesan berikutnya: Bernd P. Ziller: "Re: Ups di get_hash_table"

Pesan sebelumnya: Linus Torvalds: "Re: I / O request booking"

On Mon, 5 Agustus 1996, Peter P. Eiserloh menulis:

Kita perlu menjaga konsep benang tetap jelas. Terlalu banyak orang tampaknya mengacaukan utas dengan suatu proses. Diskusi berikut ini tidak mencerminkan keadaan linux saat ini, tetapi lebih merupakan upaya untuk tetap pada diskusi tingkat tinggi.

TIDAK!

Tidak ada alasan untuk berpikir bahwa "utas" dan "proses" adalah entitas yang terpisah. Begitulah cara tradisional dilakukan, tetapi saya pribadi berpikir itu adalah kesalahan besar untuk berpikir seperti itu. Satu-satunya alasan untuk berpikir seperti itu adalah bagasi bersejarah.

Baik utas dan proses benar-benar hanya satu hal: "konteks eksekusi". Mencoba membedakan kasus yang berbeda secara artifisial hanya bisa dilakukan sendiri.

"Konteks eksekusi", dengan ini disebut COE, hanyalah konglomerat dari semua keadaan COE itu. Keadaan itu mencakup hal-hal seperti keadaan CPU (register dll), keadaan MMU (pemetaan halaman), keadaan perizinan (uid, gid) dan berbagai "keadaan komunikasi" (file terbuka, penangan sinyal, dll). Secara tradisional, perbedaan antara "utas" dan "proses" terutama adalah bahwa utas memiliki status CPU (+ mungkin beberapa kondisi minimal lainnya), sementara semua konteks lainnya berasal dari proses. Namun, itu baru satu cara untuk membagi keadaan total COE, dan tidak ada yang mengatakan bahwa itu adalah cara yang tepat untuk melakukannya. Membatasi diri Anda dengan citra seperti itu benar-benar bodoh.

Cara Linux berpikir tentang hal ini (dan seperti yang saya inginkan hal yang kerja) adalah bahwa ada adalah tidak ada hal seperti itu sebagai "proses" atau "benang". Hanya ada totalitas COE (disebut "tugas" oleh Linux). COE yang berbeda dapat berbagi bagian dari konteksnya satu sama lain, dan satu subset dari berbagi itu adalah pengaturan "utas" / "proses" tradisional, tetapi itu harus benar-benar dilihat sebagai HANYA subset (ini adalah subset yang penting, tetapi yang penting datang bukan dari desain, tetapi dari standar: kami jelas ingin menjalankan program utas yang sesuai standar di atas Linux juga).

Singkatnya: JANGAN mendesain di sekitar utas / proses cara berpikir. Kernel harus dirancang di sekitar cara berpikir COE, dan kemudian pthreads library dapat mengekspor antarmuka pthreads terbatas ke pengguna yang ingin menggunakan cara memandang COE itu.

Sama seperti contoh apa yang menjadi mungkin ketika Anda berpikir COE sebagai lawan dari utas / proses:

  • Anda dapat melakukan program "cd" eksternal, sesuatu yang secara tradisional tidak mungkin di UNIX dan / atau proses / utas (contoh konyol, tetapi idenya adalah Anda dapat memiliki "modul" semacam ini yang tidak terbatas pada UNIX tradisional) / pengaturan utas). Lakukan:

clone (CLONE_VM | CLONE_FS);

child: execve ("external-cd");

/ * the "execve ()" akan melepaskan VM, jadi satu-satunya alasan kami menggunakan CLONE_VM adalah untuk membuat tindakan kloning lebih cepat * /

  • Anda dapat melakukan "vfork ()" secara alami (ini memberikan dukungan kernel minimal, tetapi dukungan itu cocok dengan cara berpikir CUA dengan sempurna):

klon (CLONE_VM);

anak: terus berjalan, akhirnya mengeksekusi ()

ibu: tunggu eksekusi

  • Anda dapat melakukan "IO deamons" eksternal:

clone (CLONE_FILES);

child: deskriptor file terbuka dll

ibu: gunakan fd anak dibuka dan ay.

Semua hal di atas bekerja karena Anda tidak terikat pada utas / cara berpikir. Pikirkan server web misalnya, di mana skrip CGI dilakukan sebagai "utas eksekusi". Anda tidak dapat melakukan itu dengan utas tradisional, karena utas tradisional selalu harus membagikan seluruh ruang alamat, jadi Anda harus menautkan semua yang ingin Anda lakukan di server web itu sendiri ("utas" tidak dapat berjalan dieksekusi lainnya).

Memikirkan hal ini sebagai masalah "konteks eksekusi", tugas Anda sekarang dapat memilih untuk mengeksekusi program eksternal (= pisahkan ruang alamat dari orang tua) dll jika mereka mau, atau mereka dapat misalnya berbagi semuanya dengan orang tua kecuali untuk deskriptor file (sehingga sub-"utas" dapat membuka banyak file tanpa orang tua perlu khawatir tentang mereka: mereka menutup secara otomatis ketika sub-"utas" keluar, dan itu tidak menggunakan fd di induknya) .

Pikirkan "inetd" yang berulir, misalnya. Anda ingin fork + exec overhead rendah, jadi dengan cara Linux Anda bisa daripada menggunakan "fork ()" Anda menulis inetd multi-threaded di mana setiap utas dibuat hanya dengan CLONE_VM (ruang alamat berbagi, tetapi jangan berbagi file deskriptor dll). Kemudian anak dapat mengeksekusi jika itu adalah layanan eksternal (rlogind, misalnya), atau mungkin itu adalah salah satu layanan internal inetd (echo, timeofday) dalam hal ini ia hanya melakukan hal itu dan keluar.

Anda tidak dapat melakukannya dengan "utas" / "proses".

Linus


12

Mencoba menjawabnya dari Tampilan Kernel Linux

Suatu program menjadi suatu proses ketika diluncurkan ke dalam memori. Suatu proses memiliki ruang alamatnya sendiri yang berarti memiliki berbagai segmen dalam memori seperti segmen .textuntuk menyimpan kode yang dikompilasi, .bssuntuk menyimpan variabel statis atau global yang tidak diinisialisasi, dll.
Setiap proses akan memiliki penghitung program sendiri dan tumpukan ruang pengguna .

Di dalam kernel, setiap proses akan memiliki tumpukan kernel sendiri (yang dipisahkan dari tumpukan ruang pengguna untuk masalah keamanan) dan struktur bernama task_structyang umumnya diabstraksi sebagai blok kontrol proses, menyimpan semua informasi mengenai proses seperti prioritasnya, menyatakan , (dan banyak potongan lainnya).
Suatu proses dapat memiliki beberapa utas eksekusi.

Datang ke utas, mereka berada di dalam suatu proses dan berbagi ruang alamat dari proses induk bersama dengan sumber daya lain yang dapat dilewati selama pembuatan utas seperti sumber daya sistem file, berbagi sinyal tertunda, berbagi data (variabel dan instruksi) sehingga membuat utas menjadi lebih ringan dan karenanya memungkinkan pergantian konteks yang lebih cepat.

Di dalam kernel, setiap thread memiliki tumpukan kernel sendiri bersama dengan task_structstruktur yang mendefinisikan thread. Oleh karena itu kernel melihat thread dari proses yang sama dengan entitas yang berbeda dan dapat dijadwalkan sendiri. Utas dalam proses yang sama berbagi id umum yang disebut sebagai grup id benang ( tgid), juga mereka memiliki id unik yang disebut sebagai id proses ( pid).


11

Mencoba menjawab pertanyaan ini berkaitan dengan dunia Jawa.

Suatu proses adalah eksekusi suatu program tetapi utas adalah urutan eksekusi tunggal dalam proses tersebut. Suatu proses dapat berisi banyak utas. Sebuah utas terkadang disebut proses yang ringan .

Sebagai contoh:

Contoh 1: JVM berjalan dalam satu proses dan utas di JVM berbagi tumpukan milik proses itu. Itulah sebabnya beberapa utas dapat mengakses objek yang sama. Thread berbagi heap dan memiliki ruang stack sendiri. Ini adalah bagaimana permohonan satu thread pada suatu metode dan variabel lokalnya menjaga agar thread tetap aman dari utas lainnya. Tetapi heap tidak aman untuk benang dan harus disinkronkan untuk keamanan benang.

Contoh 2: Suatu program mungkin tidak dapat menggambar dengan membaca penekanan tombol. Program harus memberikan perhatian penuh pada input keyboard dan kurang memiliki kemampuan untuk menangani lebih dari satu peristiwa pada suatu waktu akan menimbulkan masalah. Solusi ideal untuk masalah ini adalah eksekusi mulus dari dua atau lebih bagian dari suatu program pada saat yang bersamaan. Utas memungkinkan kita melakukan ini. Di sini Menggambar gambar adalah suatu proses dan membaca keystroke adalah sub proses (utas).


1
Jawaban yang bagus, saya suka itu mendefinisikan ruang lingkupnya (dunia Java) dan memberikan beberapa contoh yang berlaku - termasuk satu (# 2) yang siapa pun yang harus mengajukan pertanyaan asli dapat segera mengaitkannya.
Smithers

9

Perbedaan antara Thread dan Proses?

Suatu proses adalah turunan dari aplikasi dan utas adalah jalur eksekusi dalam suatu proses. Juga, suatu proses dapat berisi beberapa utas. Penting untuk dicatat bahwa utas dapat melakukan apa pun yang bisa dilakukan suatu proses. Tetapi karena suatu proses dapat terdiri dari beberapa utas, utas dapat dianggap sebagai proses yang 'ringan'. Dengan demikian, perbedaan mendasar antara utas dan proses adalah pekerjaan yang masing-masing digunakan untuk menyelesaikannya. Utas digunakan untuk tugas kecil, sedangkan proses digunakan untuk tugas yang lebih 'berat' - pada dasarnya pelaksanaan aplikasi.

Perbedaan lain antara utas dan proses adalah bahwa utas dalam proses yang sama berbagi ruang alamat yang sama, sedangkan proses yang berbeda tidak. Ini memungkinkan utas untuk membaca dan menulis ke struktur dan variabel data yang sama, dan juga memfasilitasi komunikasi antar utas. Komunikasi antar proses - juga dikenal sebagai IPC, atau komunikasi antar proses - cukup sulit dan membutuhkan banyak sumber daya.

Berikut ringkasan perbedaan antara utas dan proses:

  1. Utas lebih mudah dibuat daripada proses karena tidak memerlukan ruang alamat terpisah.

  2. Multithreading memerlukan pemrograman yang cermat karena utas berbagi struktur data yang hanya boleh dimodifikasi oleh satu utas pada satu waktu. Tidak seperti utas, proses tidak berbagi ruang alamat yang sama.

  3. Thread dianggap ringan karena mereka menggunakan sumber daya yang jauh lebih sedikit daripada proses.

  4. Proses tidak tergantung satu sama lain. Utas, karena mereka berbagi ruang alamat yang sama saling bergantung, jadi hati-hati harus diambil agar utas yang berbeda tidak saling menginjak.
    Ini benar-benar cara lain untuk menyatakan # 2 di atas.

  5. Suatu proses dapat terdiri dari beberapa utas.


9

Berikut ini adalah apa yang saya dapatkan dari salah satu artikel di The Code Project . Saya kira itu menjelaskan semua yang dibutuhkan dengan jelas.

Utas adalah mekanisme lain untuk memisahkan beban kerja menjadi aliran eksekusi yang terpisah. Seutas benang lebih ringan daripada proses. Ini berarti, ia menawarkan fleksibilitas yang lebih rendah daripada proses penuh, tetapi dapat dimulai lebih cepat karena ada lebih sedikit untuk mengatur Sistem Operasi. Ketika suatu program terdiri dari dua utas atau lebih, semua utas berbagi ruang memori tunggal. Proses diberikan ruang alamat yang terpisah. semua utas berbagi satu tumpukan. Tetapi setiap utas diberi tumpukannya sendiri.


1
Tidak yakin apakah ini jelas, kecuali berasal dari perspektif yang sudah memahami thread vs proses. Menambahkan bagaimana mereka berhubungan satu sama lain mungkin bermanfaat.
Smithers

Tidak jelas. Apakah ini berarti hanya satu proses dan utasnya? Bagaimana jika ada banyak proses dengan banyak utas di masing-masing? Apakah semua utas tersebut berbagi ruang memori tunggal? Dari semua proses itu?
Hijau

9

Proses:

Proses pada dasarnya adalah suatu program dalam pelaksanaan. Ini adalah entitas aktif. Beberapa sistem operasi menggunakan istilah 'tugas' untuk merujuk ke program yang sedang dijalankan. Suatu proses yang selalu disimpan dalam memori utama juga disebut sebagai memori primer atau memori akses acak. Oleh karena itu, suatu proses disebut sebagai entitas aktif. Hilang jika mesin reboot. Beberapa proses dapat dikaitkan dengan program yang sama. Pada sistem multiprosesor, banyak proses dapat dieksekusi secara paralel. Pada sistem uni-prosesor, meskipun paralelisme sejati tidak tercapai, algoritma penjadwalan proses diterapkan dan prosesor dijadwalkan untuk mengeksekusi setiap proses satu per satu menghasilkan ilusi konkurensi. Contoh: Menjalankan beberapa instance dari program 'Kalkulator'. Masing-masing contoh disebut sebagai suatu proses.

Benang:

Thread adalah bagian dari proses. Ini disebut sebagai 'proses ringan', karena mirip dengan proses nyata tetapi dieksekusi dalam konteks suatu proses dan berbagi sumber daya yang sama yang dialokasikan untuk proses oleh kernel. Biasanya, suatu proses hanya memiliki satu utas kontrol - satu set instruksi mesin yang dijalankan pada satu waktu. Suatu proses dapat juga terdiri dari beberapa utas eksekusi yang mengeksekusi instruksi secara bersamaan. Beberapa utas kontrol dapat mengeksploitasi paralelisme sebenarnya yang dimungkinkan pada sistem multiprosesor. Pada sistem uni-prosesor, algoritma penjadwalan thread diterapkan dan prosesor dijadwalkan untuk menjalankan setiap utas pada satu waktu. Semua utas yang berjalan dalam suatu proses berbagi ruang alamat yang sama, deskriptor file, tumpukan, dan atribut terkait proses lainnya. Karena utas proses berbagi memori yang sama,

ref- https://practice.geeksforgeeks.org/problems/difference-between-process-and-thread


Kedengarannya seperti konkurensi Node dalam satu proses VS paralelisme multi-utas bahasa lain
user2734550

Ini benar-benar disalin dari jawaban di bawah ini dari 2010 ...
mc01

8

Dari sudut pandang pewawancara, pada dasarnya hanya ada 3 hal utama yang ingin saya dengar, selain hal-hal yang jelas seperti proses dapat memiliki banyak utas:

  1. Thread berbagi ruang memori yang sama, yang berarti utas dapat mengakses memori dari memori utas lainnya. Proses biasanya tidak bisa.
  2. Sumber daya. Sumber daya (memori, pegangan, soket, dll) dilepaskan pada saat penghentian proses, bukan penghentian thread.
  3. Keamanan. Suatu proses memiliki token keamanan tetap. Sebaliknya, utas dapat menyamar sebagai pengguna / token yang berbeda.

Jika Anda menginginkan lebih, respons Scott Langham mencakup banyak hal. Semua ini dari perspektif sistem operasi. Bahasa yang berbeda dapat menerapkan konsep yang berbeda, seperti tugas, utas ringan dan sebagainya, tetapi mereka hanya cara menggunakan utas (serat pada Windows). Tidak ada utas perangkat keras dan lunak. Ada pengecualian dan interupsi perangkat keras dan perangkat lunak , atau mode pengguna dan utas kernel .


Ketika Anda mengatakan token keamanan, apakah maksud Anda kredensial pengguna (nama pengguna / pass) seperti yang ada di linux, misalnya?

Di windows ini adalah topik yang kompleks, token keamanan (sebenarnya disebut Access Token) adalah struktur besar, berisi semua informasi yang diperlukan untuk pemeriksaan akses. Struktur dibuat setelah otorisasi, yang berarti tidak ada nama pengguna / kata sandi, tetapi, daftar SID / hak berdasarkan nama pengguna / kata sandi. Lebih detail di sini: msdn.microsoft.com/en-us/library/windows/desktop/…
AndreiM

8
  1. Thread berjalan di ruang memori bersama, tetapi sebuah proses berjalan di ruang memori terpisah
  2. Thread adalah proses yang ringan, tetapi suatu proses adalah proses yang berat.
  3. Thread adalah subtipe proses.

Ini terasa sangat rekursif. Ini akan menjadi jawaban yang lebih baik mungkin jika hubungan antara utas dan proses diperluas.
Smithers

7

Bagi mereka yang lebih nyaman dengan belajar dengan memvisualisasikan, berikut adalah diagram praktis yang saya buat untuk menjelaskan Proses dan Utas.
Saya menggunakan informasi dari MSDN - Tentang Proses dan Utas

Proses dan Utas


1
Mungkin menarik untuk menambahkan proses lain hanya untuk melihat bagaimana multithreading dibandingkan dengan multiprocessing.
Bram Vanroy

6

Berasal dari dunia tertanam, saya ingin menambahkan bahwa konsep proses hanya ada di prosesor "besar" ( CPU desktop, ARM Cortex A-9 ) yang memiliki MMU (unit manajemen memori), dan sistem operasi yang mendukung menggunakan MMU ( seperti Linux ). Dengan prosesor / mikrokontroler kecil / tua dan sistem operasi RTOS kecil (sistem operasi waktu nyata ), seperti freeRTOS, tidak ada dukungan MMU dan karenanya tidak ada proses tetapi hanya utas.

Thread dapat mengakses memori satu sama lain, dan mereka dijadwalkan oleh OS secara interleaved sehingga mereka tampaknya berjalan secara paralel (atau dengan multi-core mereka benar-benar berjalan secara paralel).

Proses , di sisi lain, hidup di kotak pasir pribadi dari memori virtual, disediakan dan dijaga oleh MMU. Ini berguna karena memungkinkan:

  1. menjaga proses buggy agar tidak menabrak seluruh sistem.
  2. Menjaga keamanan dengan membuat data proses lainnya tidak terlihat dan tidak dapat dijangkau. Pekerjaan aktual di dalam proses ditangani oleh satu atau lebih utas.

6
  1. Pada dasarnya, utas adalah bagian dari proses tanpa utas proses tidak akan berfungsi.
  2. Sebuah thread ringan sedangkan prosesnya adalah kelas berat.
  3. komunikasi antara proses membutuhkan waktu sedangkan utas membutuhkan lebih sedikit waktu.
  4. Utas dapat berbagi area memori yang sama sedangkan proses hidup terpisah.

6

Proses : program yang sedang dieksekusi dikenal sebagai proses

Utas : Utas adalah fungsi yang dijalankan dengan bagian lain dari program berdasarkan konsep "satu dengan yang lain" sehingga utas adalah bagian dari proses ..


Tidak buruk, meskipun memperkenalkan konsep baru ("satu dengan yang lain") yang mungkin asing bagi seseorang yang mengajukan pertanyaan.
Smithers

Posting diformat sebagai kode tetapi harus berupa teks biasa.
Heinrich

6

Saya telah membaca hampir semua jawaban di sana, sayangnya, sebagai mahasiswa sarjana yang mengambil kursus OS saat ini saya tidak dapat memahami kedua konsep secara menyeluruh. Maksud saya sebagian besar orang membaca dari beberapa buku OS perbedaannya yaitu utas dapat mengakses ke variabel global dalam unit transaksi karena mereka menggunakan ruang alamat proses mereka. Namun, pertanyaan baru muncul mengapa ada proses, secara sadar kita tahu bahwa utas lebih ringan dibandingkan proses vis-à-vis. Mari kita lihat contoh berikut dengan memanfaatkan gambar yang dikutip dari salah satu jawaban sebelumnya ,

Kami memiliki 3 utas yang bekerja sekaligus pada dokumen kata misalnya Libre Office . Yang pertama melakukan pemeriksaan ejaan dengan menggarisbawahi jika kata tersebut salah eja. Yang kedua mengambil dan mencetak huruf dari keyboard. Dan yang terakhir tidak menyimpan dokumen dalam waktu singkat untuk tidak kehilangan dokumen yang berfungsi jika terjadi kesalahan. Dalam hal ini, 3 utas tidak dapat berupa 3 proses karena mereka berbagi memori yang sama yang merupakan ruang alamat dari proses mereka dan dengan demikian semua memiliki akses ke dokumen yang sedang diedit. Jadi, jalan adalah dokumen kata bersama dengan dua buldoser yang merupakan utas meskipun salah satunya adalah kurangnya gambar.

masukkan deskripsi gambar di sini


5

Sambil membangun sebuah algoritma dengan Python (bahasa yang ditafsirkan) yang menggabungkan multi-threading, saya terkejut melihat bahwa waktu eksekusi tidak lebih baik jika dibandingkan dengan algoritma sekuensial yang saya buat sebelumnya. Dalam upaya untuk memahami alasan untuk hasil ini saya membaca, dan percaya apa yang saya pelajari menawarkan konteks yang menarik untuk lebih memahami perbedaan antara multi-threading dan multi-proses.

Sistem multi-core dapat menjalankan beberapa utas eksekusi, dan karenanya Python harus mendukung multi-threading. Tapi Python bukan bahasa yang dikompilasi dan sebaliknya adalah bahasa yang ditafsirkan 1 . Ini berarti bahwa program harus ditafsirkan untuk dijalankan, dan penerjemah tidak mengetahui program sebelum memulai eksekusi. Apa yang diketahui adalah aturan Python dan kemudian secara dinamis menerapkan aturan tersebut. Optimalisasi dalam Python harus pada dasarnya optimasi dari interpreter itu sendiri, dan bukan kode yang harus dijalankan. Ini berbeda dengan bahasa yang dikompilasi seperti C ++, dan memiliki konsekuensi untuk multi-threading di Python. Secara khusus, Python menggunakan Global Interpreter Lock untuk mengelola multi-threading.

Di sisi lain, bahasa yang dikompilasi, dikompilasi dengan baik. Program ini diproses "seluruhnya", di mana pertama ditafsirkan sesuai dengan definisi sintaksisnya, kemudian dipetakan ke representasi perantara agnostik bahasa, dan akhirnya dihubungkan ke kode yang dapat dieksekusi. Proses ini memungkinkan kode menjadi sangat optimal karena semuanya tersedia pada saat kompilasi. Berbagai interaksi dan hubungan program didefinisikan pada saat executable dibuat dan keputusan yang kuat tentang optimasi dapat dibuat.

Dalam lingkungan modern, juru bahasa Python harus mengizinkan multi-threading, dan ini harus aman dan efisien. Di sinilah perbedaan antara menjadi bahasa yang ditafsirkan dengan bahasa yang dikompilasi memasuki gambar. Penerjemah tidak boleh mengganggu data yang dibagikan secara internal dari utas yang berbeda, sementara pada saat yang sama mengoptimalkan penggunaan prosesor untuk perhitungan.

Seperti yang telah dicatat dalam posting sebelumnya baik proses dan utas adalah eksekusi sekuensial independen dengan perbedaan utama adalah bahwa memori dibagi di beberapa utas proses, sementara proses mengisolasi ruang memori mereka.

Dalam Python data dilindungi dari akses simultan oleh utas berbeda oleh Global Interpreter Lock. Ini mensyaratkan bahwa dalam program Python hanya satu utas yang dapat dijalankan kapan saja. Di sisi lain dimungkinkan untuk menjalankan banyak proses karena memori untuk setiap proses diisolasi dari proses lain, dan proses dapat berjalan pada banyak inti.


1 Donald Knuth memiliki penjelasan yang bagus tentang rutinitas interpretatif dalam The Art of Computer Programming: Fundamental Algorithms.


4

Utas dalam proses yang sama berbagi Memori, tetapi masing-masing utas memiliki susunan dan registernya sendiri, dan utas menyimpan data khusus utas di heap. Thread tidak pernah dieksekusi secara independen, sehingga komunikasi antar-thread jauh lebih cepat jika dibandingkan dengan komunikasi antar-proses.

Proses tidak pernah berbagi memori yang sama. Ketika proses anak membuat itu menduplikasi lokasi memori dari proses induk. Proses komunikasi dilakukan dengan menggunakan pipa, memori bersama, dan penguraian pesan. Pergantian konteks di antara utas sangat lambat.


4

Jawaban terbaik yang saya temukan sejauh ini adalah 'The Linux Programming Interface' Michael Kerrisk :

Dalam implementasi UNIX modern, setiap proses dapat memiliki beberapa utas eksekusi. Salah satu cara membayangkan utas adalah sebagai serangkaian proses yang berbagi memori virtual yang sama, serta serangkaian atribut lainnya. Setiap utas menjalankan kode program yang sama dan berbagi area data dan tumpukan yang sama. Namun, setiap utas memiliki tumpukan itu sendiri yang berisi variabel lokal dan informasi hubungan panggilan fungsi. [LPI 2.12]

Buku ini adalah sumber kejelasan yang luar biasa; Julia Evans menyebutkan bantuannya dalam menjelaskan bagaimana kelompok Linux benar-benar bekerja dalam artikel ini .


Ini tampaknya bertentangan secara langsung. Satu bagian mengatakan suatu proses dapat memiliki lebih dari satu utas. Bagian selanjutnya mengatakan utas adalah serangkaian proses yang berbagi memori virtual. Saya tidak melihat bagaimana kedua hal ini bisa benar.
David Schwartz

Begini cara saya membacanya: buang kata 'miliki' di kalimat pertama. Yang tersisa dengan Anda, menurut terminologi, adalah 1) satu utas dan 2) sekelompok utas, yang dikenal sebagai proses demi kenyamanan. Ini pendapat saya tentang Kerrisk setelah apa di sini.
Zach Valenta

Apa yang saya pikir dia coba katakan adalah bahwa jika Anda terbiasa dengan pandangan UNIX lama bahwa proses adalah jadwal OS maka seperangkat utas seperti seperangkat proses, kecuali mereka berbagi banyak hal.
David Schwartz

Baik! Cara yang bagus untuk menggambarkannya.
Zach Valenta

3

Contoh 1: JVM berjalan dalam satu proses dan utas di JVM berbagi tumpukan milik proses itu. Itulah sebabnya beberapa utas dapat mengakses objek yang sama. Thread berbagi heap dan memiliki ruang stack sendiri. Ini adalah bagaimana permohonan satu thread pada suatu metode dan variabel lokalnya menjaga agar thread tetap aman dari utas lainnya. Tetapi heap tidak aman untuk benang dan harus disinkronkan untuk keamanan benang.


3

Mereka hampir sama ... Tapi perbedaan utama adalah utasnya ringan dan prosesnya sangat berat dalam hal pengalihan konteks, beban kerja, dan sebagainya.


Bisakah Anda memperluas jawaban Anda?
Fiver

3
Thread adalah sub-proses, mereka berbagi sumber daya umum seperti kode, data, file dalam suatu proses. Sedangkan dua proses tidak dapat berbagi sumber daya (Pengecualian adalah jika suatu proses (induk) garpu untuk membuat proses lain (anak) maka secara default mereka dapat berbagi sumber daya.), menuntut muatan tinggi ke sumber daya ke CPU sedangkan utas jauh lebih ringan dalam Konteks ini. Meskipun keduanya memiliki hal yang sama. Skenario, pertimbangkan proses berulir tunggal diblokir karena I / 0, maka keseluruhan 1 akan masuk ke negara menunggu tetapi ketika proses multithreaded diblokir oleh i / o, maka hanya 1 i / o utas yang bersangkutan akan diblokir.
Nasir Ul Islam Butt
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.