به تکه کد زیر توجه کنید.
import asyncio
counter = 0
async def download_file():
global counter
temp_counter = counter
temp_counter += 1
await asyncio.sleep(0.01)
counter = temp_counter
async def manage_downloads():
global counter
tasks = [asyncio.create_task(download_file()) for _ in range(100)]
await asyncio.gather(*tasks)
print('counter is', counter)
asyncio.run(manage_downloads())توضیح کد بالا:
در این کد همه task هایی که ساخته میشوند مقدار counter را ۱ میبینند. برای حل این مشکل از کلاس Lock به شکل زیر استفاده میکنیم.
import asyncio
counter = 0
lock = asyncio.Lock()
async def download_file():
await lock.acquire()
global counter
temp_counter = counter
temp_counter += 1
await asyncio.sleep(0.01)
counter = temp_counter
lock.release()
async def manage_downloads():
global counter
tasks = [asyncio.create_task(download_file()) for _ in range(100)]
await asyncio.gather(*tasks)
print('counter is', counter)
asyncio.run(manage_downloads())همچنین میتوان به جای acquire و release از دستور with نیز استفاده کرد.
import asyncio
counter = 0
lock = asyncio.Lock()
async def download_file():
async with lock:
global counter
temp_counter = counter
temp_counter += 1
await asyncio.sleep(0.01)
counter = temp_counter
async def manage_downloads():
global counter
tasks = [asyncio.create_task(download_file()) for _ in range(100)]
await asyncio.gather(*tasks)
print('counter is', counter)
asyncio.run(manage_downloads())