import asyncio
import random


@asyncio.coroutine
def main():
    pool = asyncio.Semaphore(3)

    @asyncio.coroutine
    def pooled(coro):
        with (yield from pool):
            print("+ task")
            try:
                return (yield from coro)
            finally:
                print("- task")

    tasks = [
        pooled(asyncio.sleep(random.randint(1, 2)))
        for i in range(10)
    ]

    yield from asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())