Pemrograman Asynchronous Di Python - CRUDPRO

Pemrograman Asynchronous Di Python

Pemrograman Asynchronous Di Python

Pemrograman Asynchronous adalah paradigma pemrograman yang memungkinkan banyak proses untuk melakukan secara bersamaan dan independen, tanpa menunggu satu selesai sebelum melanjutkan ke yang berikutnya. Dalam postingan blog ini kita akan melihat apa itu pemrograman Asynchronous dan bagaimana cara menggunakannya dengan python.

Apa itu Pemrograman Asynchronous?

Dalam pemrograman sinkron, komputer mengeksekusi instruksi dalam urutan berurutan, memblokir eksekusi sampai pekerjaan selesai sebelum melanjutkan ke pekerjaan berikutnya.

Pemrograman Asynchronous, di sisi lain, memungkinkan program untuk memulai satu operasi dan kemudian melanjutkan ke operasi lain tanpa menghentikan eksekusi sampai tugas awal selesai.

Pemrograman Asynchronous sangat bermanfaat dalam keadaan di mana proses, seperti I/O jaringan atau operasi basis data, dapat memakan waktu lama untuk diselesaikan. Pemrograman Asynchronous dapat membantu meningkatkan kinerja dan daya tanggap dalam aplikasi perangkat lunak dengan mengizinkan program untuk melanjutkan ke aktivitas lain sambil menunggu operasi yang lambat selesai.

Bergantung pada bahasa pemrograman dan kerangka kerja yang digunakan, pemrograman Asynchronous dapat diselesaikan menggunakan berbagai strategi seperti panggilan balik, janji, atau kata kunci async/tunggu.

Perbedaan Antara Pemrograman Asynchronous dan Mutliprocessing

Perbedaan utama antara pemrograman Asynchronous dan multiprosesor adalah bahwa pemrograman Asynchronous memungkinkan operasi non-pemblokiran terjadi dalam satu utas, sementara multiprosesor menggunakan banyak inti atau proses untuk menyelesaikan pekerjaan secara bersamaan.

Perbedaan Antara Pemrograman Asynchronous dan Threading

Perbedaan utama antara pemrograman Asynchronous dan threading adalah bahwa pemrograman Asynchronous memungkinkan operasi non-pemblokiran dengan menggunakan satu utas, sementara threading menggunakan banyak utas untuk melakukan banyak tugas secara paralel.

Untuk informasi lebih lanjut tentang perbedaan: Menginjak vs Multiprosesing vs Pemrograman Asynchronous

Bagaimana cara menggunakan Asyncio?

Pertama mari kita buat program sederhana yang mulai melakukan pekerjaan sekaligus dan menyelesaikannya.

import time
import asyncio

def do_job(s):
    print(f"{s} started")
    await asyncio.sleep(1)
    print(f"{s} done")

def main():
    start = time.perf_counter()
    todo = ["Job A", "Job B", "Job C"]
    for job in todo:
        do_job(job)
    
    end = time.perf_counter()
    print(f"Took: {end-start:.3f} seconds")

main()

# OUTPUT
# Job A started
# Job Adone
# Job B started
# Job B done
# Job C started
# Job C done
# Took: 3.009 seconds

Untuk menggunakan pemrograman Asynchronous dengan Python, kita perlu menggunakan kata kunci menunggu async dan perpustakaan asyncio.

Membuat dan Menjalankan Coroutine

Coroutine adalah jenis fungsi yang dapat diinterupsi dan dilanjutkan pada waktu yang berbeda-beda selama eksekusi. Dengan kata lain, coroutine memungkinkan Anda untuk menulis kode yang dapat diinterupsi, melakukan sesuatu yang lain, dan kemudian melanjutkannya dari bagian terakhir.

Untuk membuat coroutine, kita perlu menggunakan kata kunci Asynchronous sebelum kata kunci def. Memanggil sebuah coroutine tidak memanggil fungsi yang ingin kita jalankan. Itu menciptakan tugas.

import time
import asyncio

async def do_job(s):
  ...

async def main():
  ...

main()

Jadi, seperti yang Anda lihat, main() tidak menjalankannya. Untuk menjalankannya, kita perlu menggunakan asyncio.run(task). Kita tahu bahwa main() mengembalikan tugas yang ingin kita jalankan. Jadi alihkan main() ke:

asyncio.run(main())

Menunggu kata kunci

jika Anda menjalankan kode ini, Anda mungkin mendapatkan error seperti ini:

RuntimeWarning: coroutine '...' was never awaited

Jika Anda pernah melihat kesalahan ini, mungkin itu berarti Anda lupa menggunakan fungsi ini dengan kata kunci await. Menunggu berarti menunggu sampai ini selesai dan menghentikan sementara tugas saat ini. Anda perlu menjalankan setiap coroutine dengan kata kunci menunggu.

import time
import asyncio

async def do_job(s):
    print(f"{s} started")
    await asyncio.sleep(1)
    print(f"{s} done")

async def main():
    start = time.perf_counter()
    todo = ["Job A", "Job B", "Job C"]
    for job in todo:
        await do_job(job)
    
    end = time.perf_counter()
    print(f"Took: {end-start:.3f} seconds")

asyncio.run(main())

# OUTPUT
# Job A started
# Job A done
# Job B started
# Job B done
# Job C started
# Job C done
# Took: 3.009 seconds

Seperti yang Anda lihat, kami tidak mendapatkan perbedaan. Itu karena kita menggunakan fungsi time.sleep() , yang menghentikan semua operasi pada kode kita, kita perlu mengganti ini dengan asyncio.sleep() yang merupakan coroutine.

await asyncio.sleep(1)

Tapi itu tidak mengubah hal lain juga. Jadi apa masalahnya? Ingat apa arti kata kunci await. Artinya menunggu sampai tugas selesai. Tapi kami tidak ingin menunggu sampai tugas ini selesai sebelum memulai yang berikutnya. Kami ingin memulainya bersama-sama dan menunggu hingga selesai. Kita dapat memperbaikinya dengan tugas "s" yang perlu kita alihkan untuk loop dengan:

tasks = [asyncio.create_task(do_job(item)) for item in todo]
done, pending = await asyncio.wait(tasks)

kami menggunakan asyncio.create(task) untuk membuat tugas dari coroutine do_job dan kami mulai menjalankannya secara bersamaan.

import time
import asyncio

async def do_job(s):
    print(f"{s} started")
    await asyncio.sleep(1)
    print(f"{s} done")

async def main():
    start = time.perf_counter()
    todo = ["Job A", "Job B", "Job C"]
    
    tasks = [asyncio.create_task(do_job(item)) for item in todo]
    done, pending = await asyncio.wait(tasks)
    
    end = time.perf_counter()
    print(f"Took: {end-start:.3f} seconds")

asyncio.run(main())

# OUTPUT
# Job A started
# Job B started
# Job C started
# Job A done
# Job B done
# Job C done
# Took: 1.009 seconds