2017-02-21 5 views
1

я думал ayncio и использование coroutine не связан с резьбой, так как coroutine является типом «нити» под управлением планировщиком программы, так что должна быть только одна нить работает каждый процесс. Но когда я побежал примеры в Making 1 million requests with python-aiohttp, код, как показано ниже:Почему asyncio сделать запрос с aiohttp еще использовать нить

# modified fetch function with semaphore 
import random 
import asyncio 
from aiohttp import ClientSession 

async def fetch(url, session): 
    async with session.get(url) as response: 
     delay = response.headers.get("DELAY") 
     date = response.headers.get("DATE") 
     print("{}:{} with delay {}".format(date, response.url, delay)) 
     return await response.read() 


async def bound_fetch(sem, url, session): 
    # Getter function with semaphore. 
    async with sem: 
     await fetch(url, session) 


async def run(r): 
    url = "http://localhost:8080/{}" 
    tasks = [] 
    # create instance of Semaphore 
    sem = asyncio.Semaphore(1000) 

    # Create client session that will ensure we dont open new connection 
    # per each request. 
    async with ClientSession() as session: 
     for i in range(r): 
      # pass Semaphore and session to every GET request 
      task = asyncio.ensure_future(bound_fetch(sem, url.format(i), session)) 
      tasks.append(task) 

     responses = asyncio.gather(*tasks) 
     await responses 

number = 10000 
loop = asyncio.get_event_loop() 

future = asyncio.ensure_future(run(number)) 
loop.run_until_complete(future) 

С Монитор ресурсов Windows', я обнаружил, что код создания 25 нитей в 1 процесса.

ответ

1

Стандартная библиотека Python включает в себя модуль под названием threading, который позволяет одновременно запускать код python с использованием экземпляров Thread. asyncio и aiohttp не использует модуль threading для работы.

Сам Python может использовать потоки OS (низкого уровня) в качестве детали реализации, но это, вероятно, меняется между различными платформами и версиями. Например, количество потоков ОС для простого print('hello world'); s = input() для python 3.6.0 в Windows 10 равно 3.

Откажитесь от https://github.com/python/cpython/blob/3.6/Lib/asyncio/windows_events.py, чтобы найти подсказки о том, что может запускать потоки ОС в Windows.

0

Библиотека aiohttp использует потоки для одновременного разрешения DNS по умолчанию, чтобы не блокировать цикл ввода-вывода, см. aiohttp/resolver.py. Если вы хотите асинхронный поиск DNS, вам нужно установить пакет python aiodns, который, в свою очередь, использует pycares.

Вы можете сделать:

async def fetch(url): 
    resolver = aiohttp.AsyncResolver() 
    connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET) 
    async with aiohttp.ClientSession(connector=connector) as session: 
     async with session.get(url) as resp: 
      if resp.status == 200: 
       print("success!") 

Если вы хотите установить AsyncResolver как глобальный по умолчанию, это работает для меня с aiohttp 2.2.3:

import aiohttp.resolver 
aiohttp.resolver.DefaultResolver = aiohttp.resolver.AsyncResolver 
Смежные вопросы