Уведомления

Группа в Telegram: @pythonsu

#1 Июль 15, 2009 19:29:32

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Проблема с удалением файла созданного в другом потоке.

Две минуты - это аномально много. Задержка должна быть в милисекунды.
Глупость какая-то закралась.



Офлайн

#2 Июль 15, 2009 20:04:20

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Проблема с удалением файла созданного в другом потоке.

У проблемы оказалась смешная, но непонятная причина. Оказалось что пока запущен процесс конвертирования удалить конвертированный ранее файл нельзя. Как только конвертирование заканчивается, файл успешно удаляется. Как привязан старый фал к новому процесу для меня - загадка. Может тот внешний конвертер, который я запускаю всегда имеет одинаковый pid? Как это посмотреть?

def convertFiles(not_uploaded, tempdir='c:\\tempdir'):
""" Convert all files from source and put it to temp dir"""

for filename in not_uploaded:
name = os.path.basename(filename)

line = open(filename,'r').readline().replace('\n',' ')+' \"'+ \
os.path.join(tempdir, name) +'\"'
# convert to temp file
try:
process = subprocess.Popen(line, shell=True, stdout=subprocess.PIPE)
process.wait()
except:
print >> open('logs/flyconvert.log','aw'), 'Cant convert file', line

upload_process = threading.Thread(target=uploadFiles, name="upload_thread", args=[not_uploaded, plugin_instance_list])
upload_process.start() # run uploading process

convertFiles(not_uploaded)
PS: Tут uploadFiles просто ждёт файл в папке и аплоадит его на хостинг, после чего пытается удалить, пока не удалит.

Офлайн

#3 Июль 15, 2009 23:16:03

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблема с удалением файла созданного в другом потоке.

sypper-pit
По подробнее можешь описать решение ?
На самом деле никаких особенных трюков нет. Все очень просто.
Проблему с блокировкой файла под Вин решали в одном проекте (клиент-сервер на C++, но это не важно, т.к. корень проблемы общий) двумя путями: аппаратным и програмным.
1.
Так, логи сервера (“грязными” - доходили до 1 Гб в сутки), к которым имел доступ только 1 процесс (А) на неэксклюзивную запись и 1 (Б) на неэксклюзивное чтение в какой-то момент становились заблокированными для процесса Б (и оставался заблокированным вплоть до перезагрузки) и появлялись определенные проблемы. Включение режима прямой записи на дисковом контроллере помогло устранить эту проблему.
2.
На клиенте формировалась очередь обработанных файлов, которые следовало удалить. Удалением занимался отдельный поток, который создавался через заданные промежутки времени по таймеру. Непустая очередь сохранялась в промежуточный файл и продолжала обрабатываться после следющего запуска клиента.

Вот 2-вариант мог бы подойти, но для меня пока не до конца ясна картина.

Ferroman
Может тот внешний конвертер, который я запускаю всегда имеет одинаковый pid? Как это посмотреть?
LockHunter
и
Process Explorer в помощь.



Офлайн

#4 Июль 15, 2009 23:20:48

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Проблема с удалением файла созданного в другом потоке.

1. Не пойдёт.
2. Не понял сути

Спасибо, попробую.

Офлайн

#5 Июль 16, 2009 19:37:27

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Проблема с удалением файла созданного в другом потоке.

Popen.pid - The process ID of the child process.
None or else returned from Popen.wait()?



Офлайн

#6 Ноя. 25, 2009 15:22:52

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Проблема с удалением файла созданного в другом потоке.

Совместными усилиями, вместе с коллегами, нашёл таки причину проблемы.

Суть в том, что при использовании subprocess хендлеры файлов родительского скрипта наследуются дочерними процессами. Что значит, что если есть 2 потока, в одном из которых открывают файл, а в этот момент в другом запускают какой-либо процесс через subrocess, то этот процесс тоже получает хандлер этого файла. Т.е. пока процесс subrocess будет активен, удалить или переименовать файл в другом процессе не получится, так как для этого нужен эксклюзивный доступ, которого нет, пока хандлер файла принадлежит также subrocess-процессу.
К сожалению этот момент не отображён в документации.

Побороть это можно с помощью опции close_fds. В таком случае нет наследования хандлеров, и всё нормально работает. Беда в том, что для Win-платформы это будет работать только начиная с python 2.6 и только если не перенаправлять stdin, stdout или stderr.

Спасибо всем, кто помогал в поиске решения.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version