Исключение BlockingIOError игнорируется; я должен быть обеспокоен?

1

Я пишу сценарий, который составляет 20 000 задач, каждый из которых выполняет вызов подпроцесса и TCP-вызов или два. Чтобы сделать это не весь день, я использую новый asyncio Python.

Тем не менее, меня беспокоят эти ошибки, которые Python выводит при запуске моего скрипта:

Exception ignored when trying to write to the signal wakeup fd:
BlockingIOError: [Errno 11] Resource temporarily unavailable

Он будет печатать кучу из них, но не создавать каких-либо исключений. Я получил OSError о Too many open files и ранее OSError соединения с серверами, но я использовал семафоры, чтобы разрешить только 100 подключений к каждому серверу за один раз и всего 700 соединений.

Поскольку Python не создает никаких исключений, я не могу уловить ошибки. Но это не влияет на скрипт.

Являются ли эти ошибки чем-то, о чем я должен беспокоиться? Если да, что мне нужно сделать, чтобы избавиться от них? Если нет, как мне избавиться от них, чтобы они не были в моем программном выпуске?

Кроме того, если эти ошибки являются серьезными, почему Python игнорирует их, а не создает исключение?

  • 1
    Я был бы обеспокоен этим исключением. Сигнал пробуждения fd используется asyncio, так что цикл события пробуждается по сигналу; fd - это канал, а обработчик сигнала записывает в канал один байт. Неспособность сделать это указывает на потенциально серьезное истощение системных ресурсов в этом процессе. Попробуйте выяснить, что ест ваши файловые дескрипторы, и либо увеличьте максимально допустимое количество открытых файлов для процесса, либо еще больше сократите максимальное количество открытых соединений в вашей программе.
  • 0
    @ user4815162342, что касается. Согласно ulimit -a мой лимит файлов равен 1024, и при многократном запуске ls -l /proc/PID/fd | wc -l , наибольшее количество открытых файлов, которое я получаю, составляет 692. Я не близок к максимальному количеству открытых файлов для системы
Показать ещё 1 комментарий
Теги:
python-3.x
python-asyncio

1 ответ

2
Лучший ответ

Похоже, что лимитирующим фактором является работа с множеством недолговечных subprocess. Из трекера Python:

"Исключение игнорируется при попытке записи в сигнал wakeup fd" происходит от обработчика сигнала в модулях /signalmodule.c. Проблема в том, что Python получает много сигналов SIGCHLD (тестовые скрипты создают +300 процессы в секунду на моем компьютере). Производитель (обработчик сигнала, записывающий номер сигнала в "сам"), быстрее, чем потребитель (обратный вызов BaseSelectorEventLoop._read_from_self).

С патчем я начинаю получать сообщения с 140 параллельными процессами, что намного лучше :-) IMO более 100 одновременных процессов сумасшедшие, не делайте этого дома :-) Я имею в виду процессы с очень коротким сроком службы. Предел - это количество SIGCHLD в секунду, поэтому количество процессов, которые заканчиваются на той же секунде.

Я изменил свой код, чтобы ограничить количество create_subprocess_exec сразу. Я прекратил видеть ошибки, когда я опустился ниже 35, хотя я, вероятно, поставил его на 20, чтобы быть уверенным. Ваш пробег может отличаться.

async def myTask(stuff, semaphore, loop):
    with semaphore:
        process = await asyncio.create_subprocess_exec('short_program', loop=loop)

def taskRunner(stuffs):
    loop = asyncio.get_event_loop()
    semaphore = asyncio.Semaphore(20)  # limit how many can run at a time
    tasks = [
        asyncio.ensure_future(myTask(semaphore, loop))
        for i in range(20000)
    ]
    loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
  • 0
    Хорошо копать! Вы подали отчет в трекер ошибок? Первоначальная проблема должна была быть решена несколько лет назад, но, очевидно, проблема остается.
  • 0
    @ user4815162342 Проблема говорит, что The patch doesn't solve completly the issue. Должен ли я подать отчет?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню