Блокнот ipython и дескрипторы файлов утечки
У меня проблемы с утечкой файловых дескрипторов в коде, который я запускаю в блокноте ipython. Я загружаю много файлов с urllib2
и сохранить их локально. По-видимому, urllib2
имеет историю утечек файловых дескрипторов, которые, как я подозреваю, вызывают проблемы. В конце концов я получаю IoError: Too many open files
,
В качестве обходного пути я периодически закрываю несколько сокетов, используя os.close
, К несчастью, ipython notebook
у меня много работающих розеток, которые я не хочу закрывать.
Есть ли способ, которым я могу определить, какие файловые дескрипторы / сокеты / и т.д.. принадлежат ipython
?
1 ответ
На самом деле это не ответ, а пара обходных путей, если другие обнаружат здесь проблемы с файловыми дескрипторами.
Первый обходной путь, который, вероятно, лучше, это использовать subprocess.call()
чтобы скачать файлы, которые я хочу с wget
, Это было примерно в 4 раза быстрее, чем метод ниже.
Второй обходной путь заключается в использовании нескольких удобных функций, которые я нашел в SO (которые я не могу найти в данный момент - если вы найдете это, отредактируйте это или дайте мне знать, и я сошлюсь на ссылку):
import resource
import fcntl
import os
def get_open_fds():
fds = []
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
for fd in range(0, soft):
try:
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
except IOError:
continue
fds.append(fd)
return fds
def get_file_names_from_file_number(fds):
names = []
for fd in fds:
names.append(os.readlink('/proc/self/fd/%d' % fd))
return names
С их помощью я сохраняю дескрипторы активных файлов и соответствующие имена, прежде чем начать скачивать файлы. Затем я периодически проверяю количество дескрипторов открытых файлов, и, если оно становится опасно большим, использую os.close()
на всех, которых нет в первоначальном списке (я тоже проверяю имена - дескрипторы сами перерабатываются).
Это уродливо, и иногда ipython notebook жалуется на такие вещи, как "не может сохранить историю" (вероятно, я что-то испортил, что использовал), но в остальном он работает довольно хорошо.