What are asyncio.gather, Semaphore, and asyncio.Queue used for?hard
asyncio.gather() runs multiple coroutines concurrently and collects results. Semaphore limits how many coroutines run simultaneously — essential to avoid overwhelming rate-limited APIs. asyncio.Queue enables producer-consumer patterns between coroutines without threads.
asyncio.gather(*coros) returns results in the same order as the input coroutines. Use return_exceptions=True to collect exceptions instead of raising immediately. asyncio.Semaphore(n) is a counter: only N coroutines can hold it at once, so it rate-limits concurrent calls. asyncio.timeout(seconds) (Python 3.11+) cancels a block if it takes too long; the older pattern is asyncio.wait_for(coro, timeout=5). asyncio.Queue enables sentinel-based producer-consumer pipelines; call queue.task_done() after each item and queue.join() to wait for all items to complete.