Global interpreter lock (GIL) tampaknya sering dikutip sebagai alasan utama mengapa threading dan sejenisnya adalah sentuhan yang rumit di Python - yang menimbulkan pertanyaan "Mengapa hal itu dilakukan sejak awal?"
Menjadi Bukan Programmer, saya tidak tahu mengapa itu mungkin - apa logika di balik menempatkan dalam GIL?
python
multithreading
Fomite
sumber
sumber
Jawaban:
Ada beberapa implementasi Python, misalnya, CPython, IronPython, RPython, dll.
Beberapa dari mereka memiliki GIL, beberapa tidak. Misalnya, CPython memiliki GIL:
Dari http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Aplikasi yang ditulis dalam bahasa pemrograman dengan GIL dapat dirancang untuk menggunakan proses terpisah untuk mencapai paralelisme penuh, karena setiap proses memiliki penerjemah sendiri dan pada gilirannya memiliki GIL sendiri.
Manfaat GIL
Mengapa Python (CPython dan lainnya) menggunakan GIL
Dalam CPython, kunci juru bahasa global, atau GIL, adalah mutex yang mencegah beberapa utas asli dari mengeksekusi bytecodes Python sekaligus. Kunci ini diperlukan terutama karena manajemen memori CPython tidak aman untuk thread.
GIL kontroversial karena mencegah program CPython multithreaded dari mengambil keuntungan penuh dari sistem multiprosesor dalam situasi tertentu. Perhatikan bahwa operasi yang berpotensi memblokir atau berjalan lama, seperti I / O, pemrosesan gambar, dan pengerasan angka NumPy, terjadi di luar GIL. Oleh karena itu hanya dalam program multithreaded yang menghabiskan banyak waktu di dalam GIL, menafsirkan bytecode CPython, bahwa GIL menjadi hambatan.
Python memiliki GIL yang bertentangan dengan penguncian berbutir halus karena beberapa alasan:
Lebih cepat dalam kasing tunggal.
Lebih cepat dalam kasus multi-utas untuk program terikat i / o.
Lebih cepat dalam kasus multi-threaded untuk program cpu-terikat yang melakukan pekerjaan komputasi intensif di perpustakaan C.
Itu membuat ekstensi C lebih mudah untuk ditulis: tidak akan ada pengalihan utas Python kecuali jika Anda mengizinkannya (yaitu antara makro Py_BEGIN_ALLOW_THREADS dan Py_END_ALLOW_THREADS makro).
Itu membuat membungkus perpustakaan C lebih mudah. Anda tidak perlu khawatir tentang keamanan utas. Jika pustaka tidak aman thread, Anda cukup menjaga GIL terkunci saat Anda menyebutnya.
GIL dapat dirilis oleh ekstensi C. Pustaka standar Python melepaskan GIL di sekitar setiap panggilan i / o pemblokiran. Dengan demikian GIL tidak memiliki konsekuensi untuk kinerja server terikat i / o. Anda dapat membuat server jaringan di Python menggunakan proses (fork), utas atau i / o asinkron, dan GIL tidak akan menghalangi Anda.
Perpustakaan numerik di C atau Fortran juga dapat disebut dengan GIL yang dirilis. Sementara ekstensi C Anda menunggu FFT selesai, penerjemah akan mengeksekusi utas Python lainnya. Dengan demikian GIL lebih mudah dan lebih cepat daripada penguncian berbutir halus dalam kasus ini. Ini merupakan bagian terbesar dari pekerjaan numerik. Ekstensi NumPy melepaskan GIL bila memungkinkan.
Utas biasanya merupakan cara yang buruk untuk menulis sebagian besar program server. Jika beban rendah, forking lebih mudah. Jika bebannya tinggi, asynchronous i / o dan pemrograman berbasis acara (mis. Menggunakan Python's Twisted framework) lebih baik. Satu-satunya alasan untuk menggunakan utas adalah kurangnya os.fork di Windows.
GIL adalah masalah jika, dan hanya jika, Anda melakukan pekerjaan intensif CPU dengan Python murni. Di sini Anda bisa mendapatkan desain yang lebih bersih menggunakan proses dan penyampaian pesan (mis. Mpi4py). Ada juga modul 'pemrosesan' di toko keju Python, yang memberikan proses antarmuka yang sama seperti utas (yaitu ganti threading. Mulailah dengan pemrosesan. Proses).
Utas dapat digunakan untuk mempertahankan daya tanggap GUI terlepas dari GIL. Jika GIL merusak kinerja Anda (lih. Diskusi di atas), Anda dapat membiarkan utas Anda memunculkan proses dan menunggu sampai selesai.
sumber
s/RPython/PyPy/g
. @MichaelBorgwardt Memberi alasan pro GIL adalah inti dari pertanyaan, bukan? Meskipun saya akan setuju bahwa beberapa isi dari jawaban ini (yaitu diskusi tentang alternatif) tidak penting. Dan untuk lebih baik atau lebih buruk, penghitungan ulang sekarang hampir mustahil untuk dihilangkan - itu sudah mendarah daging di seluruh API dan basis kode; hampir tidak mungkin untuk menghilangkannya tanpa menulis ulang setengah kode dan menghancurkan semua kode eksternal.multiprocessing
perpustakaan - standar sejak 2.6. Kolam pekerja adalah abstraksi super-licin untuk beberapa jenis paralelisme sederhana.Pertama: Python tidak memiliki GIL. Python adalah bahasa pemrograman. Bahasa pemrograman adalah seperangkat aturan dan batasan matematika abstrak. Tidak ada dalam Spesifikasi Bahasa Python yang mengatakan bahwa harus ada GIL.
Ada banyak implementasi berbeda dari Python. Beberapa memiliki GIL, beberapa tidak.
Satu penjelasan sederhana untuk memiliki GIL adalah bahwa menulis kode konkuren sulit. Dengan menempatkan kunci raksasa di sekitar kode Anda, Anda memaksanya untuk selalu berjalan secara seri. Masalah terpecahkan!
Dalam CPython, khususnya, satu tujuan penting adalah untuk memudahkan memperpanjang penerjemah dengan plugin yang ditulis dalam C. Sekali lagi, menulis kode konkuren sulit, sehingga dengan menjamin bahwa tidak akan ada konkurensi, membuatnya lebih mudah untuk menulis ekstensi untuk penerjemah. Plus, banyak dari ekstensi itu hanya pembungkus tipis di sekitar perpustakaan yang ada yang mungkin belum ditulis dengan concurrency.
sumber
Apa tujuan GIL?
Dokumentasi CAPI mengatakan ini tentang subjek:
Dengan kata lain, GIL mencegah korupsi negara. Program python seharusnya tidak pernah menghasilkan kesalahan segmentasi, karena hanya operasi yang aman memori yang diizinkan. GIL memperluas jaminan ini ke program multi-utas.
Apa saja alternatifnya?
Jika tujuan GIL adalah untuk melindungi negara dari korupsi, maka salah satu alternatif yang jelas adalah mengunci pada butir yang jauh lebih halus; mungkin pada level per objek. Masalah dengan ini adalah bahwa meskipun telah ditunjukkan untuk meningkatkan kinerja program multi-threaded, ia memiliki lebih banyak program overhead dan single-threaded menderita sebagai hasilnya.
sumber