Python3.2中引入的concurrent非常的好用,只用几行代码就可以编写出线程池/进程池,并且计算型任务效率和mutiprocessing.pool提供的poll和ThreadPoll相比不分伯仲,而且在IO型任务由于引入了Future的概念效率要高数倍。
而threading的话还要自己维护相关的队列防止死锁,代码的可读性也会下降,相反concurrent提供的线程池却非常的便捷,不用自己操心死锁以及编写线程池代码,由于异步的概念IO型任务也更有优势。
既然如此,如果不是为了向下兼容2.x,是不是可以完全没有必要继续使用mutiprocessing和threading了?concurrent如此的优秀。
Concurrent sememangnya sangat berguna, terutamanya menyediakan ThreadPoolExecutor dan ProcessPoolExecutor. Berbilang benang, berbilang proses. Tetapi serentak pada asasnya adalah enkapsulasi threading dan mutiprocessing. Anda boleh mengetahui dengan melihat kod sumbernya.
ThreadPoolExecutor menyediakan baris gilir tugasnya sendiri, jadi tidak perlu menulisnya sendiri. Kumpulan utas yang dipanggil hanya membandingkan bilangan utas semasa dengan saiz max_workers yang ditentukan Jika saiznya lebih kecil daripada max_workers, tugasan dibenarkan untuk mencipta utas untuk melaksanakan tugas. Anda boleh melihat kod sumber
def _adjust_thread_count(self):
Jadi, jika anda mengekalkan baris gilir sendiri, ia tidak menjadi masalah Cocurrent juga mengekalkan baris gilir secara dalaman, dan ia hanya ditulis untuk anda.
Bagi masalah kebuntuan, serentak juga boleh menyebabkan masalah kebuntuan. Biar saya berikan anda satu contoh, jalankan dan lihat
ProcessPoolExecutor juga menggunakan mutiprocessing secara dalaman. Ia boleh menggunakan sepenuhnya ciri-ciri berbilang teras dan menyingkirkan sekatan GIL. Ambil perhatian bahawa apabila mentakrifkan ProcessPoolExecutor(max_workers=2), max_workers adalah lebih besar sedikit daripada bilangan teras CPU dan tidak boleh terlalu besar. ProcessPoolExecutor secara dalaman mengekalkan call_queue untuk mengekalkan baris gilir tugas, jenisnya ialah multiprocessing.Queue. Terdapat juga benang yang menguruskan baris gilir. Ini boleh dikatakan sebagai pengoptimuman cocurrent.
Anda boleh melihat kod sumber untuk butiran diri._adjust_process_count() sebenarnya memulakan proses untuk melaksanakan tugasan anda boleh mengetahuinya dengan mengklik pada _adjust_process_count. self._queue_management_thread ialah utas yang menguruskan baris gilir
Jadi cocurrent mudah digunakan, iaitu, ia melakukan pemprosesan yang lebih baik dengan sendirinya, seperti mengekalkan baris gilir dan mengurus baris gilir, jadi anda tidak perlu risau tentangnya. Sudah tentu anda juga boleh melaksanakannya sendiri. Anda boleh mencapai ini menggunakan cocurrent. Ia boleh dicapai dengan pemprosesan benang dan mutiproses Paling teruk, anda perlu melakukan kerja tambahan sendiri. Kerana cocurrent pada asasnya menggunakan dua teras ini. Sudah tentu, adalah lebih baik jika anda mempunyai cocurrent yang lebih baik yang sudah tersedia Anda boleh menggunakannya secara langsung dan bukannya mencipta semula roda itu sendiri. Jadi yang mana satu untuk digunakan bergantung pada kebiasaan peribadi anda Sebagai contoh, saya menggunakan python2, tetapi saya tidak boleh menggunakan cocurrent. Terpaksa guna threading.
Orang di atas telah mengatakannya dengan sangat jelas, saya cuma ingin menambah sedikit.
Concurrent.future menggunakan konsep tak segerak untuk menguruskan benang/proses, tetapi ia sebenarnya tidak merangkum IO tak segerak, jadi penanya berkata Peningkatan kecekapan IO sebenarnya salah.
Serentak ialah coroutine, bukan utas, dua konsep.