Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pengaturcaraan Asynchronous dengan Asyncio

Pengaturcaraan Asynchronous dengan Asyncio

PHPz
PHPzasal
2024-07-23 16:59:24583semak imbas

Asynchronous Programming with Asyncio

Dalam dunia pengaturcaraan, konsep "tidak menyekat" adalah meluas. Pembangun JavaScript sering menggunakan istilah "tak segerak" kerana ia adalah salah satu kekuatan JavaScript. Walau bagaimanapun, untuk benar-benar memahami pengaturcaraan tak segerak, adalah penting untuk memahami konsep pengaturcaraan serentak dan selari.

Pengaturcaraan Serentak

Apabila beberapa entiti bebas berfungsi secara serentak, pengaturcaraan adalah serentak. Ini tidak semestinya bermakna bahawa tugasan ini berjalan pada masa yang sama. Sebaliknya, ini bermakna bahawa tugasan membuat kemajuan dari semasa ke semasa dengan berkongsi sumber, seperti masa CPU. Kelebihan utama pengaturcaraan serentak ialah keteguhannya: jika satu proses ranap, seluruh program anda akan terus berfungsi.

Pengaturcaraan Selari

Jika algoritma boleh membahagikan kerjanya kepada beberapa bahagian, ia adalah selari. Lebih banyak pemproses yang anda miliki, lebih banyak anda mendapat manfaat daripada keselarian. Pengaturcaraan selari yang cekap mengoptimumkan sumber mesin moden untuk prestasi yang lebih baik.

Menggambarkan Konkurensi lwn. Paralelisme dengan Memasak

Concurrency Concurrency:

Bayangkan anda sedang menyediakan hidangan di mana anda perlu memanggang sedikit daging dan membuat sos. Anda mulakan dengan meletakkan daging di atas barbeku. Semasa daging dipanggang, anda memotong tomato dan sayur-sayuran lain untuk sos. Kemudian, anda mula mendidihkan sos sambil sesekali memeriksa daging. Di sini, kedua-dua tugas (memanggang daging dan membuat sos) sedang dijalankan, tetapi anda sedang mengalihkan perhatian anda di antara mereka. Ini mewakili keselarasan.

Contoh Paralelisme:

Sekarang, katakan anda mempunyai rakan untuk membantu anda. Semasa anda menumpukan pada memanggang daging, rakan anda menguruskan membuat sos. Kedua-dua tugas sedang dilakukan serentak tanpa perlu menukar perhatian antara mereka. Ini mewakili keselarian.

Apakah itu Pengaturcaraan Asynchronous?

Pengaturcaraan tak segerak melibatkan pengendalian operasi input/output (I/O) yang berlaku di luar program anda, seperti input pengguna, mencetak ke terminal, membaca dari soket atau menulis ke cakera. Ciri utama I/O tak segerak ialah:

  • Masa yang diambil oleh operasi tidak bergantung kepada CPU. Sebaliknya, ia bergantung pada faktor seperti kelajuan cakera, kependaman rangkaian dan keadaan luaran yang lain.

  • Program tidak dapat meramalkan bila operasi akan tamat.

Untuk perkhidmatan dengan I/O yang ketara (seperti pelayan web, pangkalan data dan skrip penggunaan), mengoptimumkan operasi ini boleh meningkatkan prestasi dengan ketara.

Mari lihat contoh kod sekatan dan kod tidak sekat.

Contoh Kod Sekat dan Tidak Sekat

Pertimbangkan program mudah:

import time

def task():
    time.sleep(2)
    print("Hello")

for _ in range(3):
    task()

Dalam atur cara segerak ini, setiap tugasan menunggu sehingga tugasan sebelumnya selesai, menyebabkan kelewatan.

Sekarang, mari lihat versi tak segerak menggunakan asyncio:

import asyncio

async def task():
    await asyncio.sleep(2)
    print("Hello")

async def main():
    tasks = [task() for _ in range(3)]
    await asyncio.gather(*tasks)

asyncio.run(main())

Dalam atur cara tak segerak ini, tugasan dijalankan serentak, mengurangkan jumlah masa pelaksanaan. Mari terokai komponen pengaturcaraan tak segerak.

Komponen Pengaturcaraan Asynchronous

Gelung acara, coroutine dan niaga hadapan ialah elemen penting bagi program Python tak segerak.

  • Gelung Peristiwa: Mengurus penukaran tugas dan aliran pelaksanaan, menjejaki tugas untuk dijalankan secara tidak segerak.

  • Coroutine: Fungsi khas yang boleh dijeda dan disambung semula, membolehkan tugasan lain dijalankan semasa menunggu. Coroutine menentukan di mana dalam fungsi peristiwa penukaran tugas harus berlaku, mengembalikan kawalan ke gelung acara. Coroutine biasanya dibuat oleh gelung acara dan disimpan secara dalaman dalam baris gilir tugas.

  • Niaga Hadapan: Pemegang tempat untuk hasil daripada coroutine, menyimpan hasil atau pengecualian. Sebaik sahaja gelung acara memulakan coroutine, masa depan yang sepadan dicipta yang menyimpan hasil coroutine, atau pengecualian jika satu dilemparkan semasa pelaksanaan coroutine.

Dengan menjelaskan bahagian penting pengaturcaraan tak segerak dalam Python, mari tulis beberapa kod.

Menulis Kod Asynchronous

Sekarang anda memahami corak pengaturcaraan tak segerak, mari tulis sedikit skrip dan analisis pelaksanaan. Berikut ialah skrip tak segerak yang mudah:

import asyncio

async def task():
    await asyncio.sleep(2)
    print("Hello")

async def main():
    tasks = [task() for _ in range(3)]
    await asyncio.gather(*tasks)

asyncio.run(main())

Dalam kod di atas, kami cuba meneruskan pelaksanaan tugas lain walaupun satu lagi yang melaksanakan sedang tidur (menyekat). Perhatikan kata kunci async di hadapan tugas dan fungsi utama.

Fungsi tersebut kini coroutine.

Coroutines functions in Python are preceded by the keyword async. The main() function here is the task coordinator or our single event loop, as it executes all tasks using the async.gather method. The asyncio.gather function runs awaitable objects concurrently.

Output:

Hello
Hello
Hello
Program executed in 2.01 seconds.

When each task reaches await asyncio.sleep(2), it simply goes to the next task and comes back when it's finished. It's like saying, "I am going to sleep for 2 seconds. Do something else."

Let's see the synchronous version for a quick comparison.

import time

def task():
    time.sleep(2)
    print("Hello")

for _ in range(3):
    task()

In the code above, we are going the traditional programming way in Python. You will notice that the execution of the process will take much more time.

Output:

Hello
Hello
Hello
Program executed in 6.01 seconds.

Now you can notice the execution time. Think of time.sleep() as a blocking task and asyncio.sleep() as a non-blocking or long task. In asynchronous programming, the benefit of awaiting something, like asyncio.sleep(), is that the surrounding function can temporarily cede control to another function that is ready to execute immediately.

With some basic examples of asynchronous programming in Python understood, let's explore the rules of asynchronous programming in Python.

Rules of Asyncio Programming

  1. Coroutines: Coroutines cannot be executed directly. If you try to run a coroutine function directly, it returns a coroutine object. Instead, use asyncio.run():

    import asyncio
    
    async def hello():
        await asyncio.sleep(1)
        print('Hello')
    
    asyncio.run(hello())
    
  2. Awaitable Objects: Coroutines, futures, and tasks are the main awaitable objects. Python coroutines are awaitables and can be awaited from other coroutines.

  3. Await Keyword:await can only be used within async functions.

    async def hello():
        await asyncio.sleep(1)
        print("Hello")
    
  4. Compatibility: Not all Python modules are compatible with asynchronous programming. For example, replacing await asyncio.sleep() with time.sleep() will cause an error. You can check the list of compatible and maintained modules here.

In the next section, we will explore a common use of asynchronous programming, HTTP requests.

Program Example: Asynchronous Requests

Let's take a look at the following piece of code:

import aiohttp
import asyncio

async def fetch(session, city):
    url = f"https://www.prevision-meteo.ch/services/json/{city}"
    async with session.get(url) as response:
        data = await response.json()
        print(f"Temperature at {city}: {data['current_condition']['tmp']} C")

async def main():
    async with aiohttp.ClientSession() as session:
        cities = ['paris', 'toulouse', 'marseille']
        tasks = [fetch(session, city) for city in cities]
        await asyncio.gather(*tasks)

asyncio.run(main())

In the code above, we create two asynchronous functions: one to fetch data from the prevision-meteo URL and a main function to execute the processes in the Python code. The goal is to send asynchronous HTTP GET requests to retrieve temperatures and print the responses.

In the main and fetch functions, we use async with. In the fetch function, async with ensures that the connection is closed properly. In the main function, it ensures that the ClientSession is closed after completing the requests. These practices are important in asynchronous coding in Python to manage resources efficiently and prevent leaks.

In the last line of the main function, we use await asyncio.gather(*tasks). In our case, it runs all tasks concurrently, allowing the program to send multiple HTTP requests simultaneously. Using await ensures that the program waits for all tasks to complete before proceeding.

Output:

Temperature at marseille: 25 C
Temperature at toulouse: 24 C
Temperature at paris: 18 C
Program executed in 5.86 seconds.

Synchronous Version for Comparison

Code:

import requests
import time

def fetch(city):
    url = f"https://www.prevision-meteo.ch/services/json/{city}"
    response = requests.get(url)
    data = response.json()
    print(f"Temperature at {city}: {data['current_condition']['tmp']} C")

def main():
    cities = ['paris', 'toulouse', 'marseille']
    for city in cities:
        fetch(city)

start_time = time.time()
main()
print(f"Program executed in {time.time() - start_time:.2f} seconds.")

Output:

Temperature at Paris: 18 C
Temperature at Toulouse: 24 C
Temperature at Marseille: 25 C
Program executed in 9.01 seconds.

When to Use Asynchronous Programming

The asynchronous model performs best when:

  • There are a large number of tasks, ensuring at least one task can always progress.

  • Tasks involve significant I/O, causing an asynchronous program to waste lots of time blocking when other tasks could be running.

  • Tasks are largely independent, minimizing inter-task communication (and thus for one task to wait upon another).

Conclusion

In this tutorial, we covered:

  • The concepts of asynchronous programming and related concepts.

  • Effective use of async/await.

  • Making asynchronous HTTP requests with aiohttp.

  • The benefits of asynchronous programming.

Thanks for reading. The second part will cover asynchronous programming with Django.

Resources

  • Python Documentation: Coroutines and Tasks

  • Python Documentation: asyncio - Asynchronous I/O

  • aiohttp Documentation

  • Aio Libraries

  • Concurrency vs Parallelism

Atas ialah kandungan terperinci Pengaturcaraan Asynchronous dengan Asyncio. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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 sebelumnya:SIMULATOR CPUArtikel seterusnya:SIMULATOR CPU