Apa perbedaan antara benang dan serat?

187

Apa perbedaan antara benang dan serat? Saya pernah mendengar tentang serat dari ruby ​​dan saya pernah mendengar bahwa serat itu tersedia dalam bahasa lain, bisakah seseorang menjelaskan kepada saya secara sederhana apa perbedaan antara benang dan serat.

tatsuhirosatou
sumber

Jawaban:

163

Dalam istilah yang paling sederhana, benang umumnya dianggap preemptive (meskipun ini mungkin tidak selalu benar, tergantung pada sistem operasi) sementara serat dianggap ringan, benang kooperatif. Keduanya merupakan jalur eksekusi yang terpisah untuk aplikasi Anda.

Dengan utas: jalur eksekusi saat ini dapat terputus atau didahului kapan saja (catatan: pernyataan ini adalah generalisasi dan mungkin tidak selalu benar tergantung pada OS / paket threading / dll.). Ini berarti bahwa untuk utas, integritas data adalah masalah besar karena satu utas dapat dihentikan di tengah pembaruan sepotong data, meninggalkan integritas data dalam keadaan buruk atau tidak lengkap. Ini juga berarti bahwa sistem operasi dapat memanfaatkan banyak CPU dan inti CPU dengan menjalankan lebih dari satu utas pada saat yang sama dan menyerahkannya kepada pengembang untuk menjaga akses data.

Dengan serat: jalur eksekusi saat ini hanya terganggu ketika serat menghasilkan eksekusi (catatan yang sama seperti di atas). Ini berarti bahwa serat selalu mulai dan berhenti di tempat yang terdefinisi dengan baik, sehingga integritas data jauh dari masalah. Juga, karena serat sering dikelola dalam ruang pengguna, sakelar konteks mahal dan perubahan status CPU tidak perlu dibuat, membuat perubahan dari satu serat ke serat berikutnya menjadi sangat efisien. Di sisi lain, karena tidak ada dua serat yang dapat berjalan pada waktu yang sama, hanya menggunakan serat saja tidak akan memanfaatkan banyak CPU atau beberapa inti CPU.

Jason Coco
sumber
7
Apakah ada cara untuk menggunakan beberapa utas untuk mengeksekusi serat secara paralel?
Baradé
2
Jawab saat berbagi variabel, kita tidak perlu menggunakan "mekanisme penguncian" dan variabel volatil? Atau maksud Anda bahwa kami masih perlu melakukan hal-hal itu?
Pacerier
@ Baradé Ini pertanyaan yang menarik, apakah Anda menemukan jawaban?
Mayur
57

Thread menggunakan penjadwalan pre-emptive , sedangkan serat menggunakan penjadwalan kooperatif .

Dengan utas, aliran kontrol bisa terganggu kapan saja, dan utas lain dapat mengambil alih. Dengan beberapa prosesor, Anda dapat menjalankan semua utas sekaligus pada saat yang bersamaan ( multithreading simultan , atau SMT). Akibatnya, Anda harus sangat berhati-hati tentang akses data bersamaan, dan melindungi data Anda dengan mutex, semaphore, variabel kondisi, dan sebagainya. Seringkali sangat sulit untuk memperbaikinya.

Dengan serat, kontrol hanya beralih saat Anda menyuruhnya, biasanya dengan pemanggilan fungsi bernama sesuatu yield(). Ini membuat akses data bersamaan lebih mudah, karena Anda tidak perlu khawatir tentang atomicity struktur data atau mutex. Selama Anda tidak menghasilkan, tidak ada bahaya preempted dan serat lain mencoba membaca atau memodifikasi data yang sedang Anda kerjakan. Namun, sebagai hasilnya, jika serat Anda masuk ke loop tak terbatas, tidak ada serat lain yang bisa berjalan, karena Anda tidak menghasilkan.

Anda juga dapat mencampur benang dan serat, yang menimbulkan masalah yang dihadapi oleh keduanya. Tidak disarankan, tetapi kadang-kadang bisa menjadi hal yang benar untuk dilakukan jika dilakukan dengan hati-hati.

Adam Rosenfield
sumber
3
Saya pikir infinite loop hanyalah bug yang perlu diperbaiki, dan utas hanya memiliki keuntungan yang cukup tidak jelas ketika ada infinite loop. Konsep non-buggy terkait adalah ketika ada proses jangka panjang yang ingin dibatalkan oleh pengguna. Dalam hal ini, apakah Anda menggunakan utas atau serat, proses yang berjalan lama harus kooperatif - hanya dengan mematikan utasnya dapat membuat beberapa struktur data Anda berantakan, jadi salah satu cara yang lebih baik adalah mis. Proses yang berjalan lama akan memeriksa secara berkala jika sudah terputus. Ini tidak jauh berbeda dari serat yang menghasilkan secara berkala.
Evgeni Sergeev
43

Di Win32, serat adalah sejenis utas yang dikelola pengguna. Serat memiliki tumpukan sendiri dan penunjuk instruksi sendiri, dll., Tetapi serat tidak dijadwalkan oleh OS: Anda harus memanggil SwitchToFiber secara eksplisit. Utas, sebaliknya, sudah ditentukan sebelumnya oleh sistem operasi. Jadi kira-kira berbicara serat adalah utas yang dikelola pada level aplikasi / runtime daripada menjadi utas OS yang sebenarnya.

Konsekuensinya adalah serat lebih murah dan aplikasi memiliki kontrol lebih besar atas penjadwalan. Ini bisa menjadi penting jika aplikasi menciptakan banyak tugas bersamaan, dan / atau ingin mengoptimalkan ketika mereka menjalankannya. Misalnya, server basis data mungkin memilih untuk menggunakan serat daripada utas.

(Mungkin ada penggunaan lain untuk istilah yang sama; seperti disebutkan, ini adalah definisi Win32.)

itowlson
sumber
37

Pertama saya akan merekomendasikan membaca penjelasan ini tentang perbedaan antara proses dan utas sebagai bahan latar belakang.

Setelah Anda membaca bahwa itu sangat mudah. Thread dapat diimplementasikan baik di kernel, di ruang pengguna, atau keduanya bisa dicampur. Serat pada dasarnya adalah benang yang diterapkan di ruang pengguna.

  • Apa yang biasanya disebut utas adalah utas eksekusi yang diterapkan di kernel: apa yang dikenal sebagai utas kernel. Penjadwalan utas kernel ditangani secara eksklusif oleh kernel, meskipun utas kernel dapat secara sukarela melepaskan CPU dengan tidur jika diinginkan. Utas kernel memiliki keuntungan karena dapat menggunakan pemblokiran I / O dan membiarkan kernel khawatir tentang penjadwalan. Kerugian utamanya adalah bahwa penggantian ulir relatif lambat karena membutuhkan penjebakan ke kernel.
  • Serat adalah utas ruang pengguna yang penjadwalannya ditangani dalam ruang pengguna oleh satu atau lebih utas kernel dalam satu proses tunggal. Ini membuat pengalihan serat sangat cepat. Jika Anda mengelompokkan semua serat yang mengakses kumpulan data tertentu di bawah konteks utas kernel tunggal dan penjadwalannya ditangani oleh satu utas kernel tunggal, maka Anda dapat menghilangkan masalah sinkronisasi karena serat akan berjalan secara efektif dalam serial dan Anda telah menyelesaikan kontrol atas penjadwalan mereka. Mengelompokkan serat terkait di bawah utas kernel tunggal adalah penting, karena utas kernel yang mereka jalankan dapat diawali oleh kernel. Poin ini tidak dijelaskan dalam banyak jawaban lainnya. Juga, jika Anda menggunakan pemblokiran I / O dalam sebuah serat, seluruh utas kernel itu adalah bagian dari blok termasuk semua serat yang merupakan bagian dari utas kernel tersebut.

Di bagian 11.4 "Proses dan Utas di Windows Vista" di Sistem Operasi Modern, Tanenbaum berkomentar:

Meskipun serat dijadwalkan secara kooperatif, jika ada beberapa thread menjadwalkan serat, banyak sinkronisasi yang cermat diperlukan untuk memastikan serat tidak saling mengganggu. Untuk menyederhanakan interaksi antara benang dan serat, sering kali berguna untuk membuat hanya sebanyak benang karena ada prosesor untuk menjalankannya, dan memperkuat benang untuk masing-masing berjalan hanya pada satu set berbeda dari prosesor yang tersedia, atau bahkan hanya satu prosesor. Setiap thread kemudian dapat menjalankan subset tertentu dari serat, membangun hubungan satu ke-banyak antara benang dan serat yang menyederhanakan sinkronisasi. Meski begitu masih banyak kesulitan dengan serat. Sebagian besar pustaka Win32 sama sekali tidak menyadari serat, dan aplikasi yang mencoba menggunakan serat seolah-olah mereka adalah thread akan mengalami berbagai kegagalan. Kernel tidak memiliki pengetahuan tentang serat, dan ketika serat memasuki kernel, utas yang dijalankannya dapat memblokir dan kernel akan menjadwalkan utas yang sewenang-wenang pada prosesor, membuatnya tidak dapat menjalankan serat lainnya. Untuk alasan ini serat jarang digunakan kecuali ketika porting kode dari sistem lain yang secara eksplisit membutuhkan fungsionalitas yang disediakan oleh serat.

Robert S. Barnes
sumber
4
Ini jawaban yang paling lengkap.
Bernard
12

Perhatikan bahwa selain Thread dan Serat, Windows 7 memperkenalkan Penjadwalan Mode Pengguna :

User-mode scheduling (UMS) adalah mekanisme ringan yang dapat digunakan aplikasi untuk menjadwalkan utas mereka sendiri. Aplikasi dapat beralih di antara utas UMS dalam mode pengguna tanpa melibatkan penjadwal sistem dan mendapatkan kembali kendali prosesor jika utas blok UMS di kernel. Utas UMS berbeda dari serat karena setiap utas UMS memiliki konteks utas sendiri alih-alih berbagi konteks utas dari utas tunggal. Kemampuan untuk beralih di antara utas dalam mode pengguna membuat UMS lebih efisien daripada kumpulan utas untuk mengelola sejumlah besar item kerja durasi pendek yang memerlukan beberapa panggilan sistem.

Informasi lebih lanjut tentang utas, serat, dan UMS tersedia dengan menonton Dave Probert: Di dalam Windows 7 - Penjadwal Mode Pengguna (UMS) .

Grant Wagner
sumber
7

Utas dijadwalkan oleh OS (pre-emptive). Sebuah thread dapat dihentikan atau dilanjutkan kapan saja oleh OS, tetapi serat lebih atau kurang mengelola diri mereka sendiri (kooperatif) dan menghasilkan satu sama lain. Yaitu, programmer mengontrol kapan serat melakukan pemrosesan dan kapan pemrosesan beralih ke serat lain.

Arnold Spence
sumber
7

Thread umumnya mengandalkan kernel untuk menyela thread sehingga thread atau thread lain dapat berjalan (yang lebih dikenal sebagai Pre-emptive multitasking) sedangkan serat menggunakan multitasking kooperatif di mana itu adalah serat itu sendiri yang memberikan waktu berjalannya sehingga serat lain bisa berjalan.

Beberapa tautan bermanfaat yang menjelaskannya lebih baik daripada yang mungkin saya lakukan adalah:

Mike Lowen
sumber
7

Utas pada awalnya dibuat sebagai proses yang ringan. Dengan cara yang sama, serat adalah benang yang ringan, mengandalkan (secara sederhana) pada serat itu sendiri untuk menjadwalkan satu sama lain, dengan menghasilkan kontrol.

Saya kira langkah selanjutnya adalah untaian di mana Anda harus mengirim mereka sinyal setiap kali Anda ingin mereka mengeksekusi instruksi (tidak seperti anak 5yo saya :-). Di masa lalu (dan bahkan sekarang pada beberapa platform tertanam), semua utas adalah serat, tidak ada pra-emption dan Anda harus menulis utas Anda untuk berperilaku baik.

paxdiablo
sumber
3

Definisi serat Win32 sebenarnya adalah definisi "Benang Hijau" yang didirikan di Sun Microsystems. Tidak perlu membuang serat istilah pada utas sejenis, yaitu utas yang mengeksekusi di ruang pengguna di bawah kontrol kode pengguna / pustaka-benang.

Untuk mengklarifikasi argumen, lihat komentar berikut:

  • Dengan hyper-threading, multi-core CPU dapat menerima banyak utas dan mendistribusikannya pada setiap inti.
  • CPU superscalar pipelined menerima satu utas untuk dieksekusi dan menggunakan Instruction Level Parallelism (ILP) untuk menjalankan utas lebih cepat. Kita dapat berasumsi bahwa satu benang dipecah menjadi serat paralel yang berjalan di pipa paralel.
  • CPU SMT dapat menerima banyak utas dan mengerasnya menjadi serat instruksi untuk eksekusi paralel pada banyak pipa, menggunakan pipa lebih efisien.

Kita harus mengasumsikan bahwa proses terbuat dari benang dan bahwa benang harus terbuat dari serat. Dengan logika itu dalam pikiran, menggunakan serat untuk jenis utas lainnya adalah salah.

billmic
sumber
Ini menarik.
JSON