Rumah > pembangunan bahagian belakang > Tutorial Python > Python Berprestasi Tinggi: Asyncio

Python Berprestasi Tinggi: Asyncio

Susan Sarandon
Lepaskan: 2025-01-01 06:30:09
asal
951 orang telah melayarinya

High-Performance Python: Asyncio

Pengaturcaraan concurrency ialah pendekatan pengaturcaraan yang menangani pelaksanaan serentak pelbagai tugas. Dalam Python, asyncio ialah alat yang berkuasa untuk melaksanakan pengaturcaraan tak segerak. Berdasarkan konsep coroutine, asyncio boleh mengendalikan tugas intensif I/O dengan cekap. Artikel ini akan memperkenalkan prinsip asas dan penggunaan asyncio.

High-Performance Python: Asyncio

Mengapa Kami Memerlukan asyncio

Kami tahu bahawa apabila mengendalikan operasi I/O, menggunakan multithreading boleh meningkatkan kecekapan berbanding dengan satu utas biasa. Jadi, mengapa kita masih memerlukan asyncio?

Multithreading mempunyai banyak kelebihan dan digunakan secara meluas, tetapi ia juga mempunyai batasan tertentu:

  • Sebagai contoh, proses menjalankan multithreading mudah terganggu, jadi situasi keadaan perlumbaan mungkin berlaku.
  • Selain itu, terdapat kos tertentu dalam penukaran benang itu sendiri, dan bilangan utas tidak boleh ditambah selama-lamanya. Oleh itu, jika operasi I/O anda sangat berat, multithreading berkemungkinan gagal memenuhi keperluan kecekapan tinggi dan kualiti tinggi.

Tepatnya untuk menyelesaikan masalah inilah asyncio muncul.

Segerak VS Async

Mari kita bezakan dahulu antara konsep Sync (synchronous) dan Async (asynchronous).

  • Penyegerakan bermakna operasi dilaksanakan satu demi satu. Operasi seterusnya hanya boleh dilaksanakan selepas operasi sebelumnya selesai.
  • Async bermakna bahawa operasi yang berbeza boleh dilaksanakan secara bergilir-gilir. Jika salah satu operasi disekat, program tidak akan menunggu tetapi akan mencari operasi boleh laku untuk diteruskan.

Cara asyncio Berfungsi

  1. Coroutine: asyncio menggunakan coroutine untuk mencapai operasi tak segerak. Coroutine ialah fungsi khas yang ditakrifkan dengan kata kunci async. Dalam coroutine, kata kunci await boleh digunakan untuk menjeda pelaksanaan coroutine semasa dan menunggu operasi tak segerak selesai.
  2. Gelung Acara: Gelung peristiwa ialah salah satu mekanisme teras asyncio. Ia bertanggungjawab untuk menjadualkan dan melaksanakan coroutine dan mengendalikan pertukaran antara coroutine. Gelung acara akan sentiasa mengundi untuk tugasan boleh laku. Sebaik sahaja tugasan sedia (seperti apabila operasi I/O selesai atau pemasa tamat tempoh), gelung acara akan memasukkannya ke dalam baris gilir pelaksanaan dan meneruskan tugas seterusnya.
  3. Tugas Async: Dalam asyncio, kami melaksanakan coroutine dengan mencipta tugasan tak segerak. Tugas tak segerak dicipta oleh fungsi asyncio.create_task(), yang merangkum coroutine menjadi objek yang boleh ditunggu dan menyerahkannya ke gelung acara untuk diproses.
  4. Operasi I/O Asynchronous: asyncio menyediakan satu set operasi I/O asynchronous (seperti permintaan rangkaian, pembacaan dan penulisan fail, dsb.), yang boleh disepadukan dengan lancar dengan coroutine dan gelung acara melalui tunggu kata kunci. Dengan menggunakan operasi I/O tak segerak, sekatan semasa menunggu penyiapan I/O boleh dielakkan, meningkatkan prestasi program dan keselarasan.
  5. Panggil balik: asyncio juga menyokong penggunaan fungsi panggil balik untuk mengendalikan hasil operasi tak segerak. Fungsi asyncio.ensure_future() boleh digunakan untuk merangkum fungsi panggil balik ke dalam objek yang boleh ditunggu dan menyerahkannya ke gelung acara untuk diproses.
  6. Pelaksanaan Serentak: asyncio boleh melaksanakan berbilang tugas coroutine secara serentak. Gelung acara secara automatik akan menjadualkan pelaksanaan coroutine mengikut kesediaan tugas, sekali gus mencapai pengaturcaraan serentak yang cekap.

Ringkasnya, prinsip kerja asyncio adalah berdasarkan mekanisme coroutine dan gelung peristiwa. Dengan menggunakan coroutine untuk operasi tak segerak dan mempunyai gelung peristiwa yang bertanggungjawab untuk penjadualan dan pelaksanaan coroutine, asyncio merealisasikan model pengaturcaraan tak segerak yang cekap.

Coroutines dan Asynchronous Programming

Coroutine ialah konsep penting dalam asyncio. Ia adalah unit pelaksanaan ringan yang boleh bertukar dengan cepat antara tugas tanpa overhed penukaran benang. Coroutine boleh ditakrifkan dengan kata kunci async dan kata kunci await digunakan untuk menjeda pelaksanaan coroutine dan menyambung semula selepas operasi tertentu selesai.

Berikut ialah contoh kod ringkas yang menunjukkan cara menggunakan coroutine untuk pengaturcaraan tak segerak:

import asyncio

async def hello():
    print("Hello")
    await asyncio.sleep(1)  # Simulate a time-consuming operation
    print("World")

# Create an event loop
loop = asyncio.get_event_loop()

# Add the coroutine to the event loop and execute
loop.run_until_complete(hello())
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, fungsi hello() ialah coroutine yang ditakrifkan dengan kata kunci async. Di dalam coroutine, kita boleh menggunakan await untuk menjeda pelaksanaannya. Di sini, asyncio.sleep(1) digunakan untuk mensimulasikan operasi yang memakan masa. Kaedah run_until_complete() menambahkan coroutine pada gelung acara dan menjalankannya.

Operasi I/O Asynchronous

asyncio digunakan terutamanya untuk mengendalikan tugas intensif I/O, seperti permintaan rangkaian, membaca fail dan menulis. Ia menyediakan satu siri API untuk operasi I/O tak segerak, yang boleh digunakan dalam kombinasi dengan kata kunci tunggu untuk mencapai pengaturcaraan tak segerak dengan mudah.

Berikut ialah contoh kod ringkas yang menunjukkan cara menggunakan asyncio untuk permintaan rangkaian tak segerak:

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'https://www.example.com')
        print(html)

# Create an event loop
loop = asyncio.get_event_loop()

# Add the coroutine to the event loop and execute
loop.run_until_complete(main())
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, kami menggunakan perpustakaan aiohttp untuk permintaan rangkaian. Fungsi fetch() ialah coroutine. Ia memulakan permintaan GET tak segerak melalui kaedah session.get() dan menunggu respons kembali menggunakan kata kunci await. Fungsi main() ialah coroutine lain. Ia mencipta objek ClientSession di dalam untuk digunakan semula, kemudian memanggil kaedah fetch() untuk mendapatkan kandungan halaman web dan mencetaknya.

Nota: Di sini kami menggunakan aiohttp dan bukannya perpustakaan permintaan kerana perpustakaan permintaan tidak serasi dengan asyncio, manakala perpustakaan aiohttp adalah. Untuk menggunakan asyncio dengan baik, terutamanya untuk melaksanakan fungsinya yang berkuasa, dalam banyak kes, perpustakaan Python yang sepadan diperlukan.

Pelaksanaan Pelbagai Tugasan Serentak

asyncio juga menyediakan beberapa mekanisme untuk melaksanakan berbilang tugas secara serentak, seperti asyncio.gather() dan asyncio.wait(). Berikut ialah kod sampel yang menunjukkan cara menggunakan mekanisme ini untuk melaksanakan berbilang tugas coroutine secara serentak:

import asyncio

async def task1():
    print("Task 1 started")
    await asyncio.sleep(1)
    print("Task 1 finished")

async def task2():
    print("Task 2 started")
    await asyncio.sleep(2)
    print("Task 2 finished")

async def main():
    await asyncio.gather(task1(), task2())

# Create an event loop
loop = asyncio.get_event_loop()

# Add the coroutine to the event loop and execute
loop.run_until_complete(main())
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, kami mentakrifkan dua tugas coroutine task1() dan task2(), yang kedua-duanya melakukan beberapa operasi yang memakan masa. Coroutine main() memulakan kedua-dua tugasan ini secara serentak melalui asyncio.gather() dan menunggunya selesai. Pelaksanaan serentak boleh meningkatkan kecekapan pelaksanaan program.

Bagaimana untuk Memilih?

Dalam projek sebenar, patutkah kita memilih multithreading atau asyncio? Satu pukulan besar meringkaskannya dengan jelas:

import asyncio

async def hello():
    print("Hello")
    await asyncio.sleep(1)  # Simulate a time-consuming operation
    print("World")

# Create an event loop
loop = asyncio.get_event_loop()

# Add the coroutine to the event loop and execute
loop.run_until_complete(hello())
Salin selepas log masuk
Salin selepas log masuk
  • Jika ia terikat I/O dan operasi I/O perlahan, memerlukan kerjasama banyak tugas/benang, maka menggunakan asyncio adalah lebih sesuai.
  • Jika ia terikat I/O tetapi operasi I/O adalah pantas dan hanya bilangan tugasan/benang yang terhad diperlukan, maka multithreading akan dilakukan.
  • Jika ia terikat kepada CPU, maka pemprosesan berbilang diperlukan untuk meningkatkan kecekapan menjalankan program.

berlatih

Masukkan senarai. Untuk setiap elemen dalam senarai, kami ingin mengira jumlah kuasa dua semua integer daripada 0 hingga elemen ini.

Pelaksanaan Segerak

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'https://www.example.com')
        print(html)

# Create an event loop
loop = asyncio.get_event_loop()

# Add the coroutine to the event loop and execute
loop.run_until_complete(main())
Salin selepas log masuk
Salin selepas log masuk

Masa pelaksanaan ialah Pengiraan mengambil masa 16.00943413000002 saat

Pelaksanaan Asynchronous dengan concurrent.futures

import asyncio

async def task1():
    print("Task 1 started")
    await asyncio.sleep(1)
    print("Task 1 finished")

async def task2():
    print("Task 2 started")
    await asyncio.sleep(2)
    print("Task 2 finished")

async def main():
    await asyncio.gather(task1(), task2())

# Create an event loop
loop = asyncio.get_event_loop()

# Add the coroutine to the event loop and execute
loop.run_until_complete(main())
Salin selepas log masuk
Salin selepas log masuk

Masa pelaksanaan ialah Pengiraan mengambil masa 7.314132894999999 saat

Dalam kod yang dipertingkatkan ini, kami menggunakan concurrent.futures.ProcessPoolExecutor untuk mencipta kumpulan proses dan kemudian menggunakan kaedah executor.map() untuk menyerahkan tugasan dan mendapatkan hasil. Ambil perhatian bahawa selepas menggunakan executor.map(), jika anda perlu mendapatkan keputusan, anda boleh mengulangi keputusan ke dalam senarai atau menggunakan kaedah lain untuk memproses keputusan.

Pelaksanaan Multiprocessing

if io_bound:
    if io_slow:
        print('Use Asyncio')
    else:
        print('Use multi-threading')
elif cpu_bound:
    print('Use multi-processing')
Salin selepas log masuk

Masa pelaksanaan ialah Pengiraan mengambil masa 5.024221667 saat

concurrent.futures.ProcessPoolExecutor dan multiprocessing adalah kedua-dua perpustakaan untuk melaksanakan konkurensi berbilang proses dalam Python. Terdapat beberapa perbezaan:

  1. Pengekapsulan berasaskan antara muka: concurrent.futures.ProcessPoolExecutor ialah antara muka peringkat tinggi yang disediakan oleh modul concurrent.futures. Ia merangkumi fungsi berbilang proses yang mendasari, menjadikannya lebih mudah untuk menulis kod berbilang proses. Walaupun multiprocessing ialah salah satu perpustakaan standard Python, menyediakan sokongan berbilang proses yang lengkap dan membenarkan operasi terus pada proses.
  2. Penggunaan API: Penggunaan concurrent.futures.ProcessPoolExecutor adalah serupa dengan kumpulan benang. Ia menyerahkan objek boleh dipanggil (seperti fungsi) ke kolam proses untuk pelaksanaan dan mengembalikan objek Masa Depan, yang boleh digunakan untuk mendapatkan hasil pelaksanaan. multiprocessing menyediakan lebih banyak pengurusan proses peringkat rendah dan antara muka komunikasi. Proses boleh dibuat, dimulakan dan dikawal secara eksplisit, dan komunikasi antara berbilang proses boleh dilakukan menggunakan baris gilir atau paip.
  3. Skalabiliti dan Fleksibiliti: Memandangkan multiprocessing menyediakan lebih banyak antara muka peringkat rendah, ia lebih fleksibel berbanding concurrent.futures.ProcessPoolExecutor. Dengan proses operasi secara langsung, kawalan yang lebih halus boleh dicapai untuk setiap proses, seperti menetapkan keutamaan proses dan berkongsi data antara proses. concurrent.futures.ProcessPoolExecutor lebih sesuai untuk penyelarasan tugas yang mudah, menyembunyikan banyak butiran asas dan memudahkan untuk menulis kod berbilang proses.
  4. Sokongan merentas platform: Kedua-dua concurrent.futures.ProcessPoolExecutor dan multiprocessing menyediakan sokongan berbilang proses merentas platform dan boleh digunakan pada pelbagai sistem pengendalian.

Ringkasnya, concurrent.futures.ProcessPoolExecutor ialah antara muka peringkat tinggi yang merangkumi fungsi berbilang proses asas, sesuai untuk penyelarasan tugas berbilang proses yang mudah. multiprocessing ialah perpustakaan peringkat rendah, memberikan lebih kawalan dan fleksibiliti, sesuai untuk senario yang memerlukan kawalan proses yang terperinci. Anda perlu memilih perpustakaan yang sesuai mengikut keperluan khusus. Jika ia hanya penyelarasan tugasan mudah, anda boleh menggunakan concurrent.futures.ProcessPoolExecutor untuk memudahkan kod; jika lebih banyak kawalan dan komunikasi tahap rendah diperlukan, anda boleh menggunakan perpustakaan berbilang pemprosesan.

Ringkasan

Tidak seperti multithreading, asyncio adalah single-threading, tetapi mekanisme gelung peristiwa dalamannya membolehkannya menjalankan berbilang tugas yang berbeza secara serentak dan mempunyai kawalan autonomi yang lebih besar daripada multithreading.

Tugas dalam asyncio tidak akan terganggu semasa operasi, jadi situasi keadaan perlumbaan tidak akan berlaku.

Terutama dalam senario dengan operasi I/O yang berat, asyncio mempunyai kecekapan operasi yang lebih tinggi daripada multithreading. Kerana kos penukaran tugasan dalam asyncio jauh lebih kecil daripada penukaran benang dan bilangan tugasan yang boleh dimulakan oleh asyncio adalah jauh lebih besar daripada bilangan utas dalam berbilang benang.

Walau bagaimanapun, perlu diingatkan bahawa dalam banyak kes, menggunakan asyncio memerlukan sokongan perpustakaan pihak ketiga tertentu, seperti aiohttp dalam contoh sebelumnya. Dan jika operasi I/O adalah pantas dan tidak berat, menggunakan multithreading juga boleh menyelesaikan masalah dengan berkesan.

  • asyncio ialah perpustakaan Python untuk melaksanakan pengaturcaraan tak segerak.
  • Coroutine ialah konsep teras asyncio, mencapai operasi tak segerak melalui async dan menunggu kata kunci.
  • asyncio menyediakan API berkuasa untuk operasi I/O tak segerak dan boleh mengendalikan tugas intensif I/O dengan mudah.
  • Melalui mekanisme seperti asyncio.gather(), berbilang tugas coroutine boleh dilaksanakan secara serentak.

Leapcell: Platform Ideal untuk Aplikasi FastAPI, Flask dan Python Lain

Akhir sekali, izinkan saya memperkenalkan platform yang ideal untuk menggunakan Flask/FastAPI: Leapcell.

Leapcell ialah platform pengkomputeran awan yang direka khusus untuk aplikasi pengedaran moden. Model penetapan harga bayar semasa anda memastikan tiada kos terbiar, bermakna pengguna hanya membayar untuk sumber yang sebenarnya mereka gunakan.

High-Performance Python: Asyncio

  1. Sokongan Berbilang Bahasa
    • Menyokong pembangunan dalam JavaScript, Python, Go atau Rust.
  2. Pengeluaran Projek Tanpa Had Percuma
    • Hanya caj berdasarkan penggunaan. Tiada caj apabila tiada permintaan.
  3. Keberkesanan Kos yang tiada tandingan
    • Bayar semasa anda pergi, tanpa yuran terbiar.
    • Sebagai contoh, $25 boleh menyokong 6.94 juta permintaan, dengan purata masa tindak balas 60 milisaat.
  4. Pengalaman Pembangun Ringkas
    • Antara muka pengguna yang intuitif untuk persediaan mudah.
    • Saluran paip CI/CD automatik sepenuhnya dan penyepaduan GitOps.
    • Metrik dan log masa nyata, memberikan cerapan yang boleh diambil tindakan.
  5. Kebolehskalaan Mudah dan Prestasi Tinggi
    • Penskalaan automatik untuk mengendalikan konkurensi tinggi dengan mudah.
    • Sifar operasi overhed, membolehkan pembangun menumpukan pada pembangunan.

Ketahui lebih lanjut dalam dokumentasi!
Twitter Leapcell: https://x.com/LeapcellHQ

Atas ialah kandungan terperinci Python Berprestasi Tinggi: Asyncio. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan