python: функции из модулей math и os прерываются EINTR - PullRequest
3 голосов
/ 01 февраля 2012

У меня установлена ​​плата Linux на samsung SoC s3c6410 (ARM11). Я собираю rootfs с помощью buildroot: Python 2.7.1, uClibc-0.9.31. Ядро Linux: Linux buildroot 2.6.28.6 # 177 Пн. 3 октября 12:50:57 EEST 2011 armv6l GNU / Linux

Мое приложение, написанное на python, в некоторых состояниях mysterios вызывает следующие исключения:

1) Исключение:

 File "./dfbUtils.py", line 3209, in setItemData
ValueError: (4, 'Interrupted system call')

код:

currentPage=int(math.floor(float(rowId)/self.pageSize))==self.selectedPage

2) Исключение:

File "./terminalGlobals.py", line 943, in getFirmawareName
OSError: [Errno 4] Interrupted system call: 'firmware'

Код:

for fileName in os.listdir('firmware'):

Некоторая информация о приложении: оно имеет 3-7 потоков, слушает последовательные порты через модуль 'serial', использует графический интерфейс, реализованный через расширение c, которое оборачивает directfb, я не могу воспроизвести эти исключения, они не предсказуемы.

Я гуглил исключения EINTR в python, но обнаружил, что EINTR может происходить только при медленных системных вызовах и сокете, подпроцессе модулей python, а другой уже обрабатывает EINTR. Так что же происходит в моем приложении? Почему простой вызов математической функции может прервать программу в любое время, это совсем не надежно. У меня есть только предложения: ошибка ulibc, ошибка обработки ядра / hw. Но эти предложения не показывают мне решение.

Теперь я создал функции обтекания (которые перезапускают работу в случае EINTR) вокруг некоторых функций из модуля os, но обтекание математического модуля увеличит время выполнения в 2 раза. Есть другой вопрос: может ли математика быть нарушена, чем другой модуль, и как получить надежность?

P.S. Я понимаю, что библиотечный вызов (например, в libm) не системный вызов, так почему у меня «Прерванный системный вызов»?

1 Ответ

0 голосов
/ 11 марта 2012

Была старая ошибка с потоками и EINTR в uClibc (# 4994), которую они исправили в 0.9.30.Это исправление было протестировано на pthreads, поэтому я бы рекомендовал tMC проверить, как вы настраивали потоки при сборке uClibc.

Также вы можете попробовать скомпилировать с опцией malloc-simple?Это медленно, но если ваша проблема исчезнет, ​​это также может указывать на проблемы с многопоточностью:

malloc-simple тривиально просто и медленно, как патока.Он был написан с нуля для uClibc и является самой простой (и, следовательно, наименьшей) реализацией malloc.

При этом используется только системный вызов mmap() для выделения и освобождения памяти и не используется brk().системный вызов вообще, что делает его прекрасным выбором для систем без MMU с очень ограниченной памятью.Он на 100% соответствует стандартам, потокобезопасен , очень мал и высвобождает освобожденную память обратно в ОС, а не хранит ее в куче процесса для перераспределения.Это также очень медленно.

...