Найти - Пользователи
Полная версия: Запись файла в другом потоке
Начало » Python для экспертов » Запись файла в другом потоке
1
dartNNN
Никак не получается организовать запись в файл из другого потока. Пишу вот так
class Dumper(threading.Thread):
def __init__(self, to_dump, dir, fname):
self.to_dump = to_dump
self.dir = dir
self.fname = fname
threading.Thread.__init__(self)
self.daemon = True

def run(self):
some_rlock = threading.RLock()
with some_rlock:
f=open(self.dir+"\\Notes\\" + self.fname,"wb")
pickle.dump(self.to_dump,f)
f.close()
И вызываю так:
    def dump(self):
Dumper(self.MainNote, self.workdir, self.fname).start()
Цель: сделать поток-демон, который после закрытия программы сохранял бы все данные.
Цель №2: разобраться с потоками.

Результат: во время работы основной программы (тоже возможно сохранение данных) все работает. Но после выхода из программы файл с данными пустой.

Этот код я добавлял к уже работающей программе, просто не хотелось ждать окончания записи всех данных.
ziro
Нормально все работает. У Вас просто поток не успевает сдампить данные пока программа закрывается - это типичная ошибка начинающих в multithreading (я на эти грабли еще в delphi наступал).

Для того, чтобы работало нормально - необходимо дождаться окончания выполнения метода run.

Самый простой способ - это вызов Thread.join() после запуска потока.

Или внутри потока по окончании процесса сохранения кидать событие (threading.Event) а в вызывающем потоке его ждать. Само событие передавать как аргумент в конструкторе ессно. Но такая схема обычно используется, если в рабочий поток периодически чего-нить через Queue кидается.

Да кстати, лок в Вашем случае - как собаки пятая нога - они для управления доступом к общим данным между различными тредами - а у Вас все внутри одного треда делается.
Ed
Вы не поняли. Ему нужен daemon thread, который будет работать после окончания основной программы.
Ed
К сожалению это невозможно. Все daemon треды убиваются автоматически при завершении основной программы. Так что если уберете daemon = True, то все будет работать. Правда основная программа будет ждать пока ваш тред завершится, а это не то, что вы хотели.
ziro
Так что если уберете daemon = True, то все будет работать.
Кстати да - так еще проще.
Ed
Если у вас *NIX, то можно просто форкнуться и в форкнутом процессе запустить сохранение данных. Основной процесс при этом завершить, а форкнутый отработает и выйдет после сохранения данных.
dartNNN
Спасибо за разъяснения, но по ходу еще вопрос: пробовал без daemon = True, но ничего не менялось, т.е. прога также завершалась, файл по окончании также пуст был.
Ed
Вот мой код на основе вашего примера. Из вывода видно, что главный тред ждет пока другой завершится:
import threading
import os
import sys
import time

class Dumper(threading.Thread):
def __init__(self, to_dump, dire, fname):
self.to_dump = to_dump
self.dire = dire
self.fname = fname
threading.Thread.__init__(self)
#self.daemon = True

def run(self):
time.sleep(2)
some_rlock = threading.RLock()
with some_rlock:
f = open(os.path.join(self.dire, self.fname), "w")
f.write('daemon is started %s\n' % time.asctime())
f.write(self.to_dump)
time.sleep(2)
f.write('daemon is done %s\n' % time.asctime())
f.close()


print 'main is started', time.asctime()
dumper = Dumper('text1\n', '.', 'dumper.out')
dumper.start()
print 'main is stopped', time.asctime()
вывод:
$ python2.6 test24.py 
main is started Sun Apr 11 14:59:20 2010
main is stopped Sun Apr 11 14:59:20 2010
$ cat dumper.out
daemon is started Sun Apr 11 14:59:22 2010
text1
daemon is done Sun Apr 11 14:59:24 2010
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB