Apakah kolam goroutine go-langs hanya benang hijau?

47

The komentator di sini menawarkan kritik berikut benang hijau:

Saya awalnya dijual dengan model N: M sebagai sarana pemrograman acara tanpa panggilan balik. Anda dapat menulis kode yang terlihat seperti kode prosedural lama tetapi di bawahnya ada keajaiban yang menggunakan pengalihan tugas userspace setiap kali sesuatu akan diblokir. Kedengarannya bagus. Masalahnya adalah kita akhirnya menyelesaikan kompleksitas dengan lebih banyak kompleksitas. swapcontext () dan keluarga cukup maju, kerumitannya berasal dari tempat lain yang tidak disengaja.

Tiba-tiba Anda dipaksa untuk menulis scheduler userspace dan coba tebak apa yang benar-benar sulit untuk menulis scheduler yang akan melakukan pekerjaan yang lebih baik daripada jadwal Linux yang telah dilakukan bertahun-tahun oleh orang-orang di dalamnya. Sekarang Anda ingin jadwal Anda untuk membuat N thread hijau menjadi M thread fisik sehingga Anda harus khawatir tentang sinkronisasi. Sinkronisasi membawa masalah kinerja sehingga Anda mulai sekarang Anda berada di lubang kelinci baru tanpa kunci. Membangun penjadwal sangat konkuren yang benar bukanlah tugas yang mudah.

Kritik lain ada di sini :

Satu proses memalsukan banyak utas memiliki banyak masalah. Salah satunya adalah bahwa semua thread palsu terhenti karena kesalahan halaman.

Pertanyaan saya adalah - apakah goroutine go-lang (untuk kumpulan default) hanyalah utas hijau? Jika demikian - apakah mereka menjawab kritik di atas?

Hawkeye
sumber

Jawaban:

67

Saya hanya pengguna biasa, jadi ikuti yang berikut dengan sebutir garam.

Wikipedia mendefinisikan utas hijau sebagai "utas yang dijadwalkan oleh mesin virtual (VM) bukan asli oleh sistem operasi yang mendasarinya". Thread hijau meniru lingkungan multithreaded tanpa mengandalkan kemampuan OS asli, dan mereka dikelola di ruang pengguna alih-alih ruang kernel, memungkinkan mereka untuk bekerja di lingkungan yang tidak memiliki dukungan thread asli.

Go (atau lebih tepatnya dua implementasi yang ada) adalah bahasa yang hanya menghasilkan kode asli - tidak menggunakan VM. Lebih lanjut, penjadwal dalam implementasi runtime saat ini bergantung pada utas level OS (bahkan ketika GOMAXPROCS = 1). Jadi saya pikir berbicara tentang benang hijau untuk model Go agak kasar.

Go people telah menciptakan istilah goroutine terutama untuk menghindari kebingungan dengan mekanisme konkurensi lainnya (seperti coroutine atau utas atau proses ringan).

Tentu saja, Go mendukung model threading M: N, tetapi terlihat jauh lebih dekat dengan model proses Erlang, dibandingkan dengan model benang hijau Java.

Berikut adalah beberapa manfaat dari model Go dibandingkan benang hijau (seperti yang diterapkan pada JVM awal):

  • Multiple core atau CPU dapat digunakan secara efektif, dengan cara yang transparan untuk pengembang. Dengan Go, pengembang harus menjaga konkurensi. Go runtime akan menangani paralelisme. Implementasi Java Green Threads tidak berskala pada beberapa core atau CPU.

  • Panggilan sistem dan C adalah non pemblokiran untuk penjadwal (semua panggilan sistem, tidak hanya panggilan yang mendukung I / O multipleks dalam loop acara). Implementasi thread hijau bisa memblokir seluruh proses ketika panggilan sistem pemblokiran dilakukan.

  • Menyalin atau tumpukan tersegmentasi. Di Go, tidak perlu memberikan ukuran tumpukan maksimum untuk goroutine. Tumpukan tumbuh secara bertahap sesuai kebutuhan. Salah satu konsekuensinya adalah goroutine tidak membutuhkan banyak memori (4KB-8KB), sehingga sejumlah besar dari mereka dapat dengan senang hati melahirkan. Oleh karena itu penggunaan goroutine dapat meresap.

Sekarang, untuk mengatasi kritik:

  • Dengan Go, Anda tidak perlu menulis scheduler userspace: sudah disediakan dengan runtime. Ini adalah perangkat lunak yang kompleks, tetapi ini adalah masalah pengembang Go, bukan pengguna Go. Penggunaannya transparan untuk pengguna Go. Di antara para pengembang Go, Dmitri Vyukov adalah pakar dalam pemrograman lockfree / waitfree, dan ia tampaknya sangat tertarik untuk menangani masalah kinerja penjadwalan yang akhirnya terjadi. Implementasi penjadwal saat ini tidak sempurna, tetapi akan meningkat.

  • Sinkronisasi membawa masalah kinerja dan kompleksitas: ini sebagian juga benar dengan Go. Tetapi perhatikan model Go mencoba mempromosikan penggunaan saluran dan dekomposisi program yang bersih di goroutine bersamaan untuk membatasi kompleksitas sinkronisasi (mis. Berbagi data dengan berkomunikasi, alih-alih berbagi memori untuk berkomunikasi). Omong-omong, implementasi Go referensi menyediakan sejumlah alat untuk mengatasi masalah kinerja dan konkurensi, seperti profiler , dan detektor ras .

  • Mengenai kesalahan halaman dan "beberapa utas palsu", harap perhatikan Go dapat menjadwalkan goroutine atas beberapa utas sistem. Ketika satu utas diblokir karena alasan apa pun (kesalahan halaman, pemblokiran panggilan sistem), itu tidak menghalangi utas lainnya untuk terus menjadwalkan dan menjalankan goroutine lainnya. Sekarang, memang benar bahwa kesalahan halaman akan memblokir utas OS, dengan semua goroutine seharusnya dijadwalkan pada utas ini. Namun dalam praktiknya, memori Go heap tidak seharusnya ditukar. Ini akan sama di Jawa: bahasa sampah yang dikumpulkan tidak mengakomodasi memori virtual dengan sangat baik. Jika program Anda harus menangani kesalahan halaman dengan cara yang anggun, jika itu mungkin karena harus mengelola beberapa memori yang tidak ditumpuk. Dalam hal itu,

Jadi IMO, goroutine bukan thread hijau, dan bahasa Go dan implementasi saat ini sebagian besar mengatasi kritik ini.

Didier Spezia
sumber
1
Respons yang luar biasa dan terperinci untuk pertanyaan :)
Tuxdude
1
Saya suka jawaban ini, tetapi apakah Anda memiliki referensi tentang bagaimana / kapan OS-threads dibuat?
Lars
1
Salah satu kelemahan terbesar dari Bahasa Go adalah membuat thread Kernel untuk setiap panggilan sistem pemblokiran!
user1870400
8
Perhatikan bahwa artikel "utas hijau" di Wikipedia telah diubah untuk menyatakan "utas yang dijadwalkan oleh pustaka runtime atau mesin virtual (VM)"; yang berarti bahwa menurut definisi itu jawaban Anda tidak akan benar lagi, karena Go runtime melakukan penjadwalan / manajemen. Saya pikir akan lebih bermanfaat untuk mendefinisikan utas hijau sebagai utas ruang pengguna yang kontras dengan utas OS. Dan tentu saja, goroutine adalah benang hijau.
mknecht
1
2 yang @mknecht. Ini bukan tentang VM, ini tentang runtime. Dan Go pasti memiliki runtime. (yang mengelola model threading dan pengumpulan sampah).
Tim Harper