Ошибка выделения памяти Python с использованием подпроцесса. Popen

Я занимаюсь разработкой биоинформатики. У меня есть python script, который в какой-то момент вызывает программу для выполнения дорогостоящего процесса (выравнивание последовательности... требует много вычислительной мощности и памяти). Я называю это с помощью subprocess.Popen. Когда я запускаю его на тестовом диске, он завершается и заканчивается нормально. Однако, когда я запускаю его в полном файле, где он должен будет делать это несколько раз для разных наборов входов, он умирает. Подпроцесс бросает:

OSError: [Errno 12] Cannot allocate memory

Я нашел несколько ссылок здесь и здесь и здесь к аналогичным проблемам, но я не уверен, что они применяются в моем случае.

По умолчанию выравниватель последовательности попытается запросить 51000M памяти. Он не всегда так много использует, но может. Когда полный вход загружен и обработан, этого много не доступно. Тем не менее, ограничение количества, которое он запрашивает или будет пытаться использовать на более низкой сумме, которая может быть доступна при запуске, дает мне такую ​​же ошибку. Я также пробовал работать с shell = True и тем же.

Это прослушивало меня уже несколько дней. Спасибо за любую помощь.

Изменить: расширение трассировки:

File "..../python2.6/subprocess.py", line 1037, in _execute_child
    self.pid=os.fork()
OSError: [Errno 12] Cannot allocate memory

выдает ошибку.

Edit2: Запуск в python 2.6.4 на 64-разрядном ubuntu 10.4

Ответ 1

Мне очень жаль ОП. 6 лет спустя, и никто не упомянул, что это очень распространенная проблема в Unix, и на самом деле не имеет ничего общего с питоном или биоинформатикой. Вызов os.fork() временно удваивает память родительского процесса (память родительского процесса должна быть доступна дочернему процессу), прежде чем выбросить все это, чтобы выполнить exec(). Хотя эта память не всегда копируется, система должна иметь достаточно памяти, чтобы она могла быть скопирована, и, таким образом, если вы родительский процесс использует более половины системной памяти, и вы также выполняете подпроцесс даже "wc -l", вы столкнетесь с ошибкой памяти.

Решение состоит в том, чтобы использовать posix_spawn или создать все ваши подпроцессы в начале script, в то время как потребление памяти низкое, а затем использовать их позже после того, как родительский процесс сделал это с интенсивной памятью.

Поиск google с использованием ключевых инструментов "os.fork" и "memory" отобразит несколько сообщений о переполнении стека по этой теме, которые могут дополнительно объяснить, что происходит:)

Ответ 2

Я бы запустил 64-разрядный питон на 64-битной ОС.

С 32-разрядным вы можете получить только 3 ГБ оперативной памяти до того, как ОС больше не расскажет вам.

Другой альтернативой может быть использование файлов с отображением памяти для открытия файла:

http://docs.python.org/library/mmap.html

Изменить: А вы на 64-битном уровне.. возможно, причина в том, что у вас закончилось RAM + Swap.. Исправление будет заключаться в том, чтобы увеличить количество swap, возможно.

Ответ 3

Это не имеет ничего общего с Python или модулем subprocess. subprocess.Popen просто сообщает вам об ошибке, которую он получает от операционной системы. (Какую операционную систему вы используете, кстати?) От man 2 fork от Linux:

ENOMEM    fork()  failed  to  allocate  the  necessary  kernel  structures
          because memory is tight.

Вы звоните subprocess.Popen несколько раз? Если это так, я думаю, что лучшее, что вы можете сделать, это убедиться, что предыдущий вызов вашего процесса завершен и получен до следующего вызова.

Ответ 4

Используете ли вы subprocess.PIPE? У меня были проблемы и читал о проблемах, когда он использовался. Обычно временные файлы решали проблему.