asyncioãã¥ãŒã䜿çšããŠPythonã§äžŠè¡ãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ãå®è£ ããã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšã¹ã±ãŒã©ããªãã£ãåäžãããããã®å æ¬çãªã¬ã€ãã§ãã
Python Asyncio ãã¥ãŒ: 䞊è¡ãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ãç¿åŸãã
éåæããã°ã©ãã³ã°ã¯ã髿§èœã§ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«ãŸããŸãéèŠã«ãªã£ãŠããŸããPythonã®asyncio
ã©ã€ãã©ãªã¯ãã³ã«ãŒãã³ãšã€ãã³ãã«ãŒãã䜿çšããŠäžŠè¡åŠçãå®çŸããããã®åŒ·åãªãã¬ãŒã ã¯ãŒã¯ãæäŸããŸããasyncio
ãæäŸããå€ãã®ããŒã«ã®äžã§ãããã¥ãŒã¯ç¹ã«ãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ãå®è£
ããéã«ã䞊è¡ããŠå®è¡ãããã¿ã¹ã¯éã®éä¿¡ãšããŒã¿å
±æãä¿é²ããäžã§éèŠãªåœ¹å²ãæãããŸãã
ãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ã®çè§£
ãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ã¯ã䞊è¡ããã°ã©ãã³ã°ã«ãããåºæ¬çãªèšèšãã¿ãŒã³ã§ããããã¯2ã€ä»¥äžã®çš®é¡ã®ããã»ã¹ãŸãã¯ã¹ã¬ãããå«ã¿ãŸããããŒã¿ãçæãŸãã¯ã¿ã¹ã¯ãäœæãããããã¥ãŒãµãŒãšããã®ããŒã¿ãåŠçãŸãã¯æ¶è²»ããã³ã³ã·ã¥ãŒããŒã§ããéåžžã¯ãã¥ãŒã§ããå ±æãããã¡ã仲ä»åœ¹ãšããŠæ©èœãããããã¥ãŒãµãŒãã³ã³ã·ã¥ãŒããŒãå§åããããšãªãã¢ã€ãã ã远å ããã³ã³ã·ã¥ãŒããŒãé ããããã¥ãŒãµãŒã«ãã£ãŠãããã¯ãããããšãªãç¬ç«ããŠäœæ¥ã§ããããã«ããŸãããã®ãã«ãããªã³ã°ã«ãããäžŠè¡æ§ãå¿çæ§ãããã³ã·ã¹ãã å šäœã®å¹çãåäžããŸãã
ãŠã§ãã¹ã¯ã¬ã€ããŒãæ§ç¯ããã·ããªãªãèããŠã¿ãŸãããããããã¥ãŒãµãŒã¯ã€ã³ã¿ãŒãããããURLããã§ããããã¿ã¹ã¯ã§ãããã³ã³ã·ã¥ãŒããŒã¯HTMLã³ã³ãã³ããè§£æããŠé¢é£æ å ±ãæœåºããã¿ã¹ã¯ã§ããå¯èœæ§ããããŸãããã¥ãŒããªãå Žåããããã¥ãŒãµãŒã¯æ¬¡ã®URLããã§ããããåã«ã³ã³ã·ã¥ãŒããŒãåŠçãå®äºããã®ãåŸ ã€å¿ èŠããããããããŸãããããã®éãç¶ãã§ãããã¥ãŒã¯ãããã®ã¿ã¹ã¯ã䞊è¡ããŠå®è¡ã§ããããã«ããã¹ã«ãŒããããæå€§åããŸãã
Asyncio ãã¥ãŒã®ç޹ä»
asyncio
ã©ã€ãã©ãªã¯ãã³ã«ãŒãã³ã§ã®äœ¿çšã®ããã«ç¹å¥ã«èšèšãããéåæãã¥ãŒå®è£
ïŒasyncio.Queue
ïŒãæäŸããŸããåŸæ¥ã®ãã¥ãŒãšã¯ç°ãªããasyncio.Queue
ã¯ã¢ã€ãã ããã¥ãŒã«å
¥ãããšãããã¥ãŒããååŸãããšãã«éåææäœïŒawait
ïŒã䜿çšãããã¥ãŒãå©çšå¯èœã«ãªãã®ãåŸ
ã€éãã³ã«ãŒãã³ãã€ãã³ãã«ãŒãã«å¶åŸ¡ãæãæž¡ãããšãå¯èœã«ããŸãããã®éããããã³ã°åäœã¯ãasyncio
ã¢ããªã±ãŒã·ã§ã³ã§çã®äžŠè¡æ§ãå®çŸããããã«äžå¯æ¬ ã§ãã
Asyncio ãã¥ãŒã®äž»èŠã¡ãœãã
以äžã«ãasyncio.Queue
ã䜿çšããäžã§æãéèŠãªã¡ãœããã®ããã€ãã瀺ããŸãã
put(item)
: ã¢ã€ãã ããã¥ãŒã«è¿œå ããŸãããã¥ãŒãæºæ¯ïŒæå€§ãµã€ãºã«éããŠããïŒã®å Žåãã¹ããŒã¹ãå©çšå¯èœã«ãªããŸã§ã³ã«ãŒãã³ã¯ãããã¯ãããŸããéåæã§æäœãå®äºããããã«await
ã䜿çšããŸã:await queue.put(item)
ãget()
: ãã¥ãŒããã¢ã€ãã ãåé€ããè¿ããŸãããã¥ãŒã空ã®å Žåãã¢ã€ãã ãå©çšå¯èœã«ãªããŸã§ã³ã«ãŒãã³ã¯ãããã¯ãããŸããéåæã§æäœãå®äºããããã«await
ã䜿çšããŸã:await queue.get()
ãempty()
: ãã¥ãŒã空ã§ããã°True
ãè¿ããŸããããã§ãªããã°False
ãè¿ããŸããããã¯äžŠè¡ç°å¢ã§ã¯ä¿¡é Œã§ããç©ºã®ææšã§ã¯ãªãããšã«æ³šæããŠãã ãããempty()
ã®åŒã³åºããšãã®äœ¿çšã®éã«å¥ã®ã¿ã¹ã¯ãã¢ã€ãã ã远å ãŸãã¯åé€ããå¯èœæ§ãããããã§ããfull()
: ãã¥ãŒãæºæ¯ã§ããã°True
ãè¿ããŸããããã§ãªããã°False
ãè¿ããŸããempty()
ãšåæ§ã«ãããã¯äžŠè¡ç°å¢ã§ã¯ä¿¡é Œã§ããæºæ¯ã®ææšã§ã¯ãããŸãããqsize()
: ãã¥ãŒå ã®ã¢ã€ãã ã®æŠæ°ãè¿ããŸããæ£ç¢ºãªã«ãŠã³ãã¯ãäžŠè¡æäœã®ãããããã«å€ããªã£ãŠããå¯èœæ§ããããŸããjoin()
: ãã¥ãŒå ã®ãã¹ãŠã®ã¢ã€ãã ãååŸãããåŠçããããŸã§ãããã¯ããŸããããã¯éåžžãã³ã³ã·ã¥ãŒããŒããã¹ãŠã®ã¢ã€ãã ã®åŠçãå®äºããããšãéç¥ããããã«äœ¿çšãããŸãããããã¥ãŒãµãŒã¯ãååŸããã¢ã€ãã ãåŠçããåŸãqueue.task_done()
ãåŒã³åºããŸããtask_done()
: 以åã«ãã¥ãŒã«è¿œå ãããã¿ã¹ã¯ãå®äºããããšã瀺ããŸãããã¥ãŒã³ã³ã·ã¥ãŒããŒã«ãã£ãŠäœ¿çšãããŸããåget()
ã®åŸãtask_done()
ãåŒã³åºãããšã§ããã¥ãŒã«å¯ŸããŠã¿ã¹ã¯ã®åŠçãå®äºããããšãäŒããŸãã
åºæ¬çãªãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒã®äŸãå®è£ ãã
asyncio.Queue
ã®äœ¿çšæ³ããç°¡åãªãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒã®äŸã§èª¬æããŸããããã©ã³ãã ãªæ°å€ãçæãããããã¥ãŒãµãŒãšããã®æ°å€ãäºä¹ããã³ã³ã·ã¥ãŒããŒãã·ãã¥ã¬ãŒãããŸãã
import asyncio
import random
async def producer(queue: asyncio.Queue, n: int):
for _ in range(n):
# Simulate some work
await asyncio.sleep(random.random())
value = random.randint(1, 100)
print(f"Producer: Adding {value} to the queue")
await queue.put(value)
# Signal the consumer that no more items will be added
for _ in range(3): # Number of consumers
await queue.put(None)
async def consumer(queue: asyncio.Queue, id: int):
while True:
value = await queue.get()
if value is None:
print(f"Consumer {id}: Exiting.")
queue.task_done()
break
# Simulate some work
await asyncio.sleep(random.random())
result = value * value
print(f"Consumer {id}: Consumed {value}, Result: {result}")
queue.task_done()
async def main():
queue = asyncio.Queue()
num_producers = 1
num_consumers = 3
total_items = 10
producers = [asyncio.create_task(producer(queue, total_items // num_producers)) for _ in range(num_producers)]
consumers = [asyncio.create_task(consumer(queue, id)) for id in range(num_consumers)]
await asyncio.gather(*producers)
await queue.join() # Wait for all items to be processed
await asyncio.gather(*consumers)
if __name__ == "__main__":
asyncio.run(main())
ãã®äŸã§ã¯:
producer
颿°ã¯ä¹±æ°ãçæãããããããã¥ãŒã«è¿œå ããŸãããã¹ãŠã®æ°å€ãçæããåŸãå®äºããããšãã³ã³ã·ã¥ãŒããŒã«éç¥ããããã«None
ããã¥ãŒã«è¿œå ããŸããconsumer
颿°ã¯ãã¥ãŒããæ°å€ãååŸããããããäºä¹ããŠçµæãåºåããŸããNone
ã·ã°ãã«ãåãåããŸã§åŠçãç¶ããŸããmain
颿°ã¯asyncio.Queue
ãäœæãããããã¥ãŒãµãŒãšã³ã³ã·ã¥ãŒããŒã®ã¿ã¹ã¯ãéå§ããasyncio.gather
ã䜿çšããŠããããå®äºããã®ãåŸ ã¡ãŸãã- éèŠ: ã³ã³ã·ã¥ãŒããŒãã¢ã€ãã ãåŠçããåŸã
queue.task_done()
ãåŒã³åºããŸããmain()
å ã®queue.join()
ã®åŒã³åºãã¯ããã¥ãŒå ã®ãã¹ãŠã®ã¢ã€ãã ãåŠçããããŸã§ïŒã€ãŸãããã¥ãŒã«å ¥ããããåã¢ã€ãã ã«å¯ŸããŠtask_done()
ãåŒã³åºããããŸã§ïŒãããã¯ããŸãã asyncio.gather(*consumers)
ã䜿çšããŠãmain()
颿°ãçµäºããåã«ãã¹ãŠã®ã³ã³ã·ã¥ãŒããŒãçµäºããããšã確èªããŸããããã¯ãNone
ã䜿çšããŠã³ã³ã·ã¥ãŒããŒã®çµäºãéç¥ããéã«ç¹ã«éèŠã§ãã
é«åºŠãªãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³
åºæ¬çãªäŸã¯ãããè€éãªã·ããªãªã«å¯Ÿå¿ããããã«æ¡åŒµã§ããŸãã以äžã«ããã€ãã®é«åºŠãªãã¿ãŒã³ã瀺ããŸãã
è€æ°ã®ãããã¥ãŒãµãŒãšã³ã³ã·ã¥ãŒããŒ
è€æ°ã®ãããã¥ãŒãµãŒãšã³ã³ã·ã¥ãŒããŒãç°¡åã«äœæããŠãäžŠè¡æ§ãé«ããããšãã§ããŸãããã¥ãŒã¯éä¿¡ã®äžå¿ç¹ãšããŠæ©èœããã³ã³ã·ã¥ãŒããŒéã§äœæ¥ãåçã«åæ£ããŸãã
import asyncio
import random
async def producer(queue: asyncio.Queue, producer_id: int, num_items: int):
for i in range(num_items):
await asyncio.sleep(random.random() * 0.5) # Simulate some work
item = (producer_id, i)
print(f"Producer {producer_id}: Producing item {item}")
await queue.put(item)
print(f"Producer {producer_id}: Finished producing.")
# Don't signal consumers here; handle it in main
async def consumer(queue: asyncio.Queue, consumer_id: int):
while True:
item = await queue.get()
if item is None:
print(f"Consumer {consumer_id}: Exiting.")
queue.task_done()
break
producer_id, item_id = item
await asyncio.sleep(random.random() * 0.5) # Simulate processing time
print(f"Consumer {consumer_id}: Consuming item {item} from Producer {producer_id}")
queue.task_done()
async def main():
queue = asyncio.Queue()
num_producers = 3
num_consumers = 5
items_per_producer = 10
producers = [asyncio.create_task(producer(queue, i, items_per_producer)) for i in range(num_producers)]
consumers = [asyncio.create_task(consumer(queue, i)) for i in range(num_consumers)]
await asyncio.gather(*producers)
# Signal the consumers to exit after all producers have finished.
for _ in range(num_consumers):
await queue.put(None)
await queue.join()
await asyncio.gather(*consumers)
if __name__ == "__main__":
asyncio.run(main())
ãã®å€æŽãããäŸã§ã¯ãè€æ°ã®ãããã¥ãŒãµãŒãšè€æ°ã®ã³ã³ã·ã¥ãŒããŒãããŸããåãããã¥ãŒãµãŒã«ã¯äžæã®IDãå²ãåœãŠãããåã³ã³ã·ã¥ãŒããŒã¯ãã¥ãŒããã¢ã€ãã ãååŸããŠåŠçããŸãããã¹ãŠã®ãããã¥ãŒãµãŒãå®äºãããšãNone
ã®çªå
µå€ããã¥ãŒã«è¿œå ãããã³ã³ã·ã¥ãŒããŒã«ãã以äžäœæ¥ããªãããšãéç¥ããŸããéèŠãªããšã«ãçµäºããåã«queue.join()
ãåŒã³åºããŸããã³ã³ã·ã¥ãŒããŒã¯ã¢ã€ãã ãåŠçããåŸãqueue.task_done()
ãåŒã³åºããŸãã
äŸå€åŠç
å®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãçæãŸãã¯æ¶è²»ããã»ã¹äžã«çºçããå¯èœæ§ã®ããäŸå€ãåŠçããå¿
èŠããããŸãããããã¥ãŒãµãŒããã³ã³ã³ã·ã¥ãŒããŒã®ã³ã«ãŒãã³å
ã§try...except
ãããã¯ã䜿çšããŠãäŸå€ãææããé©åã«åŠçããããšãã§ããŸãã
import asyncio
import random
async def producer(queue: asyncio.Queue, producer_id: int, num_items: int):
for i in range(num_items):
try:
await asyncio.sleep(random.random() * 0.5) # Simulate some work
if random.random() < 0.1: # Simulate an error
raise Exception(f"Producer {producer_id}: Simulated error!")
item = (producer_id, i)
print(f"Producer {producer_id}: Producing item {item}")
await queue.put(item)
except Exception as e:
print(f"Producer {producer_id}: Error producing item: {e}")
# Optionally, put a special error item on the queue
# await queue.put(('ERROR', str(e)))
print(f"Producer {producer_id}: Finished producing.")
async def consumer(queue: asyncio.Queue, consumer_id: int):
while True:
item = await queue.get()
if item is None:
print(f"Consumer {consumer_id}: Exiting.")
queue.task_done()
break
try:
producer_id, item_id = item
await asyncio.sleep(random.random() * 0.5) # Simulate processing time
if random.random() < 0.05: # Simulate error during consumption
raise ValueError(f"Consumer {consumer_id}: Invalid item! ")
print(f"Consumer {consumer_id}: Consuming item {item} from Producer {producer_id}")
except Exception as e:
print(f"Consumer {consumer_id}: Error consuming item: {e}")
finally:
queue.task_done()
async def main():
queue = asyncio.Queue()
num_producers = 3
num_consumers = 5
items_per_producer = 10
producers = [asyncio.create_task(producer(queue, i, items_per_producer)) for i in range(num_producers)]
consumers = [asyncio.create_task(consumer(queue, i)) for i in range(num_consumers)]
await asyncio.gather(*producers)
# Signal the consumers to exit after all producers have finished.
for _ in range(num_consumers):
await queue.put(None)
await queue.join()
await asyncio.gather(*consumers)
if __name__ == "__main__":
asyncio.run(main())
ãã®äŸã§ã¯ããããã¥ãŒãµãŒãšã³ã³ã·ã¥ãŒããŒã®äž¡æ¹ã§ã·ãã¥ã¬ãŒãããããšã©ãŒãå°å
¥ããŠããŸããtry...except
ãããã¯ã¯ãããã®ãšã©ãŒãææããã¿ã¹ã¯ãä»ã®ã¢ã€ãã ã®åŠçãç¶è¡ã§ããããã«ããŸããã³ã³ã·ã¥ãŒããŒã¯ãäŸå€ãçºçããå Žåã§ããã¥ãŒã®å
éšã«ãŠã³ã¿ãŒãæ£ããæŽæ°ãããããã«ãfinally
ãããã¯ã§queue.task_done()
ãåŒã³åºããŸãã
åªå 床ã®é«ãã¿ã¹ã¯
å Žåã«ãã£ãŠã¯ãç¹å®ã®ã¿ã¹ã¯ãä»ã®ã¿ã¹ã¯ãããåªå
ããå¿
èŠããããããããŸãããasyncio
ã¯çŽæ¥åªå
床ä»ããã¥ãŒãæäŸããŸããããheapq
ã¢ãžã¥ãŒã«ã䜿çšããŠç°¡åã«å®è£
ã§ããŸãã
import asyncio
import heapq
import random
class PriorityQueue:
def __init__(self):
self._queue = []
self._count = 0
self._condition = asyncio.Condition(asyncio.Lock())
async def put(self, item, priority):
async with self._condition:
heapq.heappush(self._queue, (priority, self._count, item))
self._count += 1
self._condition.notify_all()
async def get(self):
async with self._condition:
while not self._queue:
await self._condition.wait()
priority, count, item = heapq.heappop(self._queue)
return item
def qsize(self):
return len(self._queue)
def empty(self):
return not self._queue
async def producer(queue: PriorityQueue, producer_id: int, num_items: int):
for i in range(num_items):
await asyncio.sleep(random.random() * 0.5) # Simulate some work
priority = random.randint(1, 10) # Assign a random priority
item = (producer_id, i)
print(f"Producer {producer_id}: Producing item {item} with priority {priority}")
await queue.put(item, priority)
print(f"Producer {producer_id}: Finished producing.")
async def consumer(queue: PriorityQueue, consumer_id: int):
while True:
item = await queue.get()
if item is None:
print(f"Consumer {consumer_id}: Exiting.")
break
producer_id, item_id = item
await asyncio.sleep(random.random() * 0.5) # Simulate processing time
print(f"Consumer {consumer_id}: Consuming item {item} from Producer {producer_id}")
async def main():
queue = PriorityQueue()
num_producers = 2
num_consumers = 3
items_per_producer = 5
producers = [asyncio.create_task(producer(queue, i, items_per_producer)) for i in range(num_producers)]
consumers = [asyncio.create_task(consumer(queue, i)) for i in range(num_consumers)]
await asyncio.gather(*producers)
# Signal consumers to exit (not needed for this example).
# for _ in range(num_consumers):
# await queue.put(None, 0)
await asyncio.gather(*consumers)
if __name__ == "__main__":
asyncio.run(main())
ãã®äŸã§ã¯ãåªå
床ã«åºã¥ããŠãœãŒãããããã¥ãŒãç¶æããããã«heapq
ã䜿çšããPriorityQueue
ã¯ã©ã¹ãå®çŸ©ããŠããŸããåªå
床ã®å€ãäœãã¢ã€ãã ãæåã«åŠçãããŸããããã§ã¯ãã¯ãqueue.join()
ãšqueue.task_done()
ã䜿çšããŠããªãããšã«æ³šæããŠãã ããããã®åªå
床ä»ããã¥ãŒã®äŸã§ã¯ãã¿ã¹ã¯ã®å®äºã远跡ããããã®çµã¿èŸŒã¿ã®æ¹æ³ããªããããã³ã³ã·ã¥ãŒããŒã¯èªåçã«çµäºããŸããããããã£ãŠãã³ã³ã·ã¥ãŒããŒã忢ããå¿
èŠãããå Žåã¯ãçµäºãéç¥ããæ¹æ³ãå®è£
ããå¿
èŠããããŸããqueue.join()
ãšqueue.task_done()
ãéèŠã§ããå Žåãåæ§ã®æ©èœããµããŒãããããã«ã«ã¹ã¿ã PriorityQueueã¯ã©ã¹ãæ¡åŒµãŸãã¯é©å¿ãããå¿
èŠããããããããŸããã
ã¿ã€ã ã¢ãŠããšãã£ã³ã»ã«
å Žåã«ãã£ãŠã¯ããã¥ãŒãžã®ã¢ã€ãã ã®ååŸãŸãã¯æå
¥ã«ã¿ã€ã ã¢ãŠããèšå®ãããããšããããããããŸãããããã«ã¯asyncio.wait_for
ã䜿çšã§ããŸãã
import asyncio
async def consumer(queue: asyncio.Queue):
while True:
try:
item = await asyncio.wait_for(queue.get(), timeout=5.0) # Timeout after 5 seconds
print(f"Consumer: Consumed {item}")
queue.task_done()
except asyncio.TimeoutError:
print("Consumer: Timeout waiting for item")
break
except asyncio.CancelledError:
print("Consumer: Cancelled")
break
async def main():
queue = asyncio.Queue()
consumer_task = asyncio.create_task(consumer(queue))
await asyncio.sleep(10) # Give the consumer some time
print("Producer: Cancelling consumer")
consumer_task.cancel()
try:
await consumer_task # Await the cancelled task to handle exceptions
except asyncio.CancelledError:
print("Main: Consumer task cancelled successfully.")
if __name__ == "__main__":
asyncio.run(main())
ãã®äŸã§ã¯ãã³ã³ã·ã¥ãŒããŒã¯ãã¥ãŒå
ã§ã¢ã€ãã ãå©çšå¯èœã«ãªããŸã§æå€§5ç§éåŸ
ã¡ãŸããã¿ã€ã ã¢ãŠãæéå
ã«ã¢ã€ãã ãå©çšå¯èœã«ãªããªãã£ãå Žåãasyncio.TimeoutError
ãçºçããŸãããŸããtask.cancel()
ã䜿çšããŠã³ã³ã·ã¥ãŒããŒã¿ã¹ã¯ããã£ã³ã»ã«ããããšãã§ããŸãã
ãã¹ããã©ã¯ãã£ã¹ãšèæ ®äºé
- ãã¥ãŒãµã€ãº: äºæ³ãããã¯ãŒã¯ããŒããšå©çšå¯èœãªã¡ã¢ãªã«åºã¥ããŠãé©åãªãã¥ãŒãµã€ãºãéžæããŠãã ãããå°ãããã¥ãŒã¯ãããã¥ãŒãµãŒãé »ç¹ã«ãããã¯ããåå ãšãªãå¯èœæ§ãããã倧ãããã¥ãŒã¯éå°ãªã¡ã¢ãªãæ¶è²»ããå¯èœæ§ããããŸããã¢ããªã±ãŒã·ã§ã³ã«æé©ãªãµã€ãºãèŠã€ããããã«å®éšããŠãã ãããäžè¬çãªã¢ã³ããã¿ãŒã³ã¯ãç¡å¶éã®ãã¥ãŒãäœæããããšã§ãã
- ãšã©ãŒåŠç: äŸå€ã«ãã£ãŠã¢ããªã±ãŒã·ã§ã³ãã¯ã©ãã·ã¥ããã®ãé²ãããã«ãå
ç¢ãªãšã©ãŒåŠçãå®è£
ããŠãã ããããããã¥ãŒãµãŒãšã³ã³ã·ã¥ãŒããŒã®äž¡æ¹ã®ã¿ã¹ã¯ã§ã
try...except
ãããã¯ã䜿çšããŠäŸå€ãææããåŠçããŸãã - ãããããã¯é²æ¢: è€æ°ã®ãã¥ãŒããã®ä»ã®åæããªããã£ãã䜿çšããéã«ã¯ããããããã¯ãé¿ããããã«æ³šæããŠãã ããã埪ç°äŸåãé²ãããã«ãã¿ã¹ã¯ããªãœãŒã¹ãäžè²«ããé åºã§è§£æŸããããšã確èªããŠãã ãããå¿
èŠã«å¿ããŠã
queue.join()
ãšqueue.task_done()
ã䜿çšããŠã¿ã¹ã¯ã®å®äºãåŠçãããããã«ããŠãã ããã - å®äºéç¥: çªå
µå€ïŒäŸ:
None
ïŒãå ±æãã©ã°ãªã©ãã³ã³ã·ã¥ãŒããŒã«å®äºãéç¥ããããã®ä¿¡é Œæ§ã®é«ãã¡ã«ããºã ã䜿çšããŠãã ããããã¹ãŠã®ã³ã³ã·ã¥ãŒããŒãæçµçã«ã·ã°ãã«ãåãåããæ£åžžã«çµäºããããšã確èªããŠãã ãããã¯ãªãŒã³ãªã¢ããªã±ãŒã·ã§ã³ã·ã£ããããŠã³ã®ããã«ãã³ã³ã·ã¥ãŒããŒã®çµäºãé©åã«éç¥ããŠãã ããã - ã³ã³ããã¹ã管ç: ãã¡ã€ã«ãããŒã¿ããŒã¹æ¥ç¶ãªã©ã®ãªãœãŒã¹ã«ã¯ã
async with
ã¹ããŒãã¡ã³ãã䜿çšããŠasyncioã¿ã¹ã¯ã³ã³ããã¹ããé©åã«ç®¡çãããšã©ãŒãçºçããå Žåã§ãé©åãªã¯ãªãŒã³ã¢ãããä¿èšŒããŸãã - ç£èŠ: ãã¥ãŒãµã€ãºããããã¥ãŒãµãŒã¹ã«ãŒããããã³ã³ã·ã¥ãŒããŒé å»¶ãç£èŠããŠãæœåšçãªããã«ããã¯ãç¹å®ããããã©ãŒãã³ã¹ãæé©åããŸãããã®ã³ã°ã¯åé¡ã®ãããã°ã«åœ¹ç«ã¡ãŸãã
- ããããã³ã°æäœã®åé¿: ã³ã«ãŒãã³å
ã§çŽæ¥ããããã³ã°æäœïŒäŸ: åæI/Oãé·æéå®è¡ãããèšç®ïŒã絶察ã«è¡ããªãã§ãã ãããããããã³ã°æäœãå¥ã®ã¹ã¬ãããŸãã¯ããã»ã¹ã«ãªãããŒãããããã«ã
asyncio.to_thread()
ãŸãã¯ããã»ã¹ããŒã«ã䜿çšããŠãã ããã
å®éã®ã¢ããªã±ãŒã·ã§ã³
asyncio
ãã¥ãŒã䜿çšãããããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ã¯ãåºç¯ãªå®éã®ã·ããªãªã«é©çšã§ããŸãã
- ãŠã§ãã¹ã¯ã¬ã€ããŒ: ãããã¥ãŒãµãŒããŠã§ãããŒãžããã§ããããã³ã³ã·ã¥ãŒããŒãããŒã¿ãè§£æããŠæœåºããŸãã
- ç»å/ãããªåŠç: ãããã¥ãŒãµãŒããã£ã¹ã¯ãŸãã¯ãããã¯ãŒã¯ããç»å/ãããªãèªã¿èŸŒã¿ãã³ã³ã·ã¥ãŒããŒãåŠçæäœïŒäŸ: ãµã€ãºå€æŽããã£ã«ã¿ãªã³ã°ïŒãå®è¡ããŸãã
- ããŒã¿ãã€ãã©ã€ã³: ãããã¥ãŒãµãŒãæ§ã ãªãœãŒã¹ïŒäŸ: ã»ã³ãµãŒãAPIïŒããããŒã¿ãåéããã³ã³ã·ã¥ãŒããŒãããŒã¿ã倿ããŠããŒã¿ããŒã¹ãŸãã¯ããŒã¿ãŠã§ã¢ããŠã¹ã«ããŒãããŸãã
- ã¡ãã»ãŒãžãã¥ãŒ:
asyncio
ãã¥ãŒã¯ãã«ã¹ã¿ã ã¡ãã»ãŒãžãã¥ãŒã·ã¹ãã ãå®è£ ããããã®æ§æèŠçŽ ãšããŠäœ¿çšã§ããŸãã - ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã«ãããããã¯ã°ã©ãŠã³ãã¿ã¹ã¯åŠç: ãããã¥ãŒãµãŒãHTTPãªã¯ãšã¹ããåä¿¡ããããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ããã¥ãŒã«å ¥ããã³ã³ã·ã¥ãŒããŒããããã®ã¿ã¹ã¯ãéåæã«åŠçããŸããããã«ãããã¡ã€ã³ã®ãŠã§ãã¢ããªã±ãŒã·ã§ã³ãã¡ãŒã«éä¿¡ãããŒã¿åŠçãªã©ã®æéã®ãããæäœã§ãããã¯ãããã®ãé²ããŸãã
- éèååŒã·ã¹ãã : ãããã¥ãŒãµãŒãåžå ŽããŒã¿ãã£ãŒããåä¿¡ããã³ã³ã·ã¥ãŒããŒãããŒã¿ãåæããŠååŒãå®è¡ããŸããasyncioã®éåææ§ã«ãããã»ãŒãªã¢ã«ã¿ã€ã ã®å¿çæéãšå€§éã®ããŒã¿ã®åŠçãå¯èœã«ãªããŸãã
- IoTããŒã¿åŠç: ãããã¥ãŒãµãŒãIoTããã€ã¹ããããŒã¿ãåéããã³ã³ã·ã¥ãŒããŒããªã¢ã«ã¿ã€ã ã§ããŒã¿ãåŠçã»åæããŸããAsyncioã«ãããã·ã¹ãã ã¯æ§ã ãªããã€ã¹ããã®å€æ°ã®åææ¥ç¶ãåŠçã§ããããã«ãªããIoTã¢ããªã±ãŒã·ã§ã³ã«é©ããŠããŸãã
Asyncio ãã¥ãŒã®ä»£æ¿ææ®µ
asyncio.Queue
ã¯åŒ·åãªããŒã«ã§ããããã¹ãŠã®ã·ããªãªã§åžžã«æé©ãªéžæè¢ãšã¯éããŸãããèæ
®ãã¹ãä»£æ¿ææ®µãããã€ã玹ä»ããŸãã
- ãã«ãããã»ã¹ãã¥ãŒ: ã¹ã¬ããã䜿çšããŠå¹ççã«äžŠååã§ããªãCPUããŠã³ããªæäœïŒã°ããŒãã«ã€ã³ã¿ãŒããªã¿ãŒãã㯠- GILã®ããïŒãå®è¡ããå¿
èŠãããå Žåã¯ã
multiprocessing.Queue
ã®äœ¿çšãæ€èšããŠãã ãããããã«ããããããã¥ãŒãµãŒãšã³ã³ã·ã¥ãŒããŒãå¥ã ã®ããã»ã¹ã§å®è¡ããGILããã€ãã¹ã§ããŸãããã ããããã»ã¹éã®éä¿¡ã¯éåžžãã¹ã¬ããéã®éä¿¡ãããã³ã¹ãããããããšã«æ³šæããŠãã ããã - ãµãŒãããŒãã£è£œã¡ãã»ãŒãžãã¥ãŒïŒäŸ: RabbitMQãKafkaïŒ: ããè€éã§åæ£ãããã¢ããªã±ãŒã·ã§ã³ã®å Žåã¯ãRabbitMQãKafkaã®ãããªå°çšã®ã¡ãã»ãŒãžãã¥ãŒã·ã¹ãã ã®äœ¿çšãæ€èšããŠãã ããããããã®ã·ã¹ãã ã¯ãã¡ãã»ãŒãžã«ãŒãã£ã³ã°ãæ°žç¶æ§ãã¹ã±ãŒã©ããªãã£ãªã©ã®é«åºŠãªæ©èœãæäŸããŸãã
- ãã£ãã«ïŒäŸ: TrioïŒ: Trioã©ã€ãã©ãªã¯ãã£ãã«ãæäŸããŠããããã¥ãŒãšæ¯èŒããŠã䞊è¡ã¿ã¹ã¯éã§éä¿¡ããããã®ããæ§é åãããæ§æå¯èœãªæ¹æ³ãæäŸããŸãã
- aiormq (asyncio RabbitMQ ã¯ã©ã€ã¢ã³ã): RabbitMQãžã®éåæã€ã³ã¿ãŒãã§ãŒã¹ãç¹ã«å¿ èŠãªå Žåã¯ãaiormqã©ã€ãã©ãªãåªããéžæè¢ã§ãã
çµè«
asyncio
ãã¥ãŒã¯ãPythonã§äžŠè¡ãããã¥ãŒãµãŒã»ã³ã³ã·ã¥ãŒããŒãã¿ãŒã³ãå®è£
ããããã®å
ç¢ã§å¹ççãªã¡ã«ããºã ãæäŸããŸãããã®ã¬ã€ãã§èª¬æããäž»èŠãªæŠå¿µãšãã¹ããã©ã¯ãã£ã¹ãçè§£ããããšã§ãasyncio
ãã¥ãŒã掻çšããŠã髿§èœã§ã¹ã±ãŒã©ãã«ãªå¿çæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸããããŸããŸãªãã¥ãŒãµã€ãºããšã©ãŒåŠçæŠç¥ãããã³é«åºŠãªãã¿ãŒã³ã詊ããŠãç¹å®ã®ããŒãºã«æé©ãªãœãªã¥ãŒã·ã§ã³ãèŠã€ããŠãã ãããasyncio
ãšãã¥ãŒã«ããéåæããã°ã©ãã³ã°ãåãå
¥ããããšã§ãèŠæ±ã®å³ããã¯ãŒã¯ããŒããåŠçããåªãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã