Izy
@Izy
Учу

Почему при подключениие через asyncio.open_connection в цикле плодятся потоки?

Друзья есть такой простой asyncio tcp клиент
import asyncio

async def tcp_echo_client(message):
    while True:
        try:
            reader, writer = await asyncio.open_connection('localhost', 9990)
        except OSError as e:
            print(f'OsError: {e}')
            await asyncio.sleep(5)
            continue
        while True:
            try:

                writer.write(message.encode())
                print(f'Send: {message!r}')
                data = await reader.read(4)
                print(f'Received: {data.decode()!r}')
                await asyncio.sleep(5)
            except  Exception as e:
                print(f'Error 2 while {e}')
                await asyncio.sleep(5)
                break
asyncio.run(tcp_echo_client('ping'))

Почему в цикле при пеерехвате ошибки OSError во время попытки подключении, когда например сервер не доступен (запускааем клеинт без серерва).
Я в htop вижу какието подпроцессы(ну или потоки) которые плодятся/ с каждым новым циклом.
5cff88892d161205794770.jpeg
  • Вопрос задан
  • 550 просмотров
Решения вопроса 1
@Taus
asyncio.open_connection порождает вызов socket.getaddrinfo в loop._default_executor, который в 3.7 по-умолчанию является ThreadPoolExecutor. Максимальное число воркеров в пуле по-умолчанию определяется max_workers = (os.cpu_count() or 1) * 5 (ссылка).
В 3.8 это изменят на min(32, (os.cpu_count() or 1) + 4), коммит.
Можете изменить число создаваемых потоков, передав свой экземпляр ThreadPoolExecutor:
import concurrent.futures
...
loop = asyncio.get_event_loop()
loop.set_default_executor(concurrent.futures.ThreadPoolExecutor(max_workers=4))
...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы