2016-09-02 11 views
1

У меня есть программа, в которой мне нужно сохранить глобальную переменную в файл. Я делаю это, используя модуль pickle.Как избежать ошибок травления при совместном использовании объектов между потоками?

У меня есть еще thread (Daemon = False, from threading module), который иногда меняет значение глобальной переменной. Значение также изменяется в глобальном масштабе (основная программа).

Я сбрасываю значение переменной в файл .pkl каждые 5 секунд (используя другой код thread от threading).

Но я обнаружил следующую ошибку, когда dump метод был выполнен:

TypeError: can't pickle _thread.lock objects 

Почему это происходит? И что я могу сделать, чтобы исправить это?

Примечание: Я нашел несколько похожих ответов с модулем multiprocessing. Но мне нужен ответ для модуля threading.

Код:

def save_state(): 
    while True: 
     global variable 

     lastSession = open('lastSession.pkl', 'wb') 

     # error occurs on this line 
     pickle.dump(variable, lastSession) 

     lastSession.close()   
     time.sleep(5) 

state_thread = threading.Thread(target = save_state) 
state_thread.setDaemon(False) 
state_thread.start() 

# variable is changed outside this function and also in another thread(not state_thread). 
+1

Вы не можете разжечь объект блокировки, потому что он привязан к текущему состоянию операционной системы/семафоров, в настоящее время удерживаемых другими потоками. –

+0

Если вы хотите рассортировать типы, которые прямо или косвенно ссылаются на блокировки, вам необходимо реализовать свой собственный ['__getstate__'] (https://docs.python.org/2/library/pickle.html#object.__getstate__). Не имеет значения, выпущены ли замки или нет, их нельзя мариновать. –

+0

Но когда целевая функция завершена, не следует ли блокировать блокировку, поскольку остается только один поток? Также, если вы можете предоставить пример кода, это действительно поможет –

ответ

0

Как уже упоминалось, вы можете не солить «летучие» Entities (нитей, соединений, Synchonization примитивов и т.д.), потому что они не имеют смысла, так как постоянные данные.

Похоже, что вы пытаетесь сохранить переменные сеанса для последующего продолжения указанной сессии. Для этой задачи вы ничего не можете сделать, чтобы сохранить объекты, которые, ну, не могут быть спасены из-за их природы.

Самое простое решение - просто проигнорировать их. Замена их некоторыми «заглушками», которые могли бы привести к ошибке в любое время, когда вы что-либо делаете с ними, не имеет никакого смысла, поскольку недостающая переменная все равно дает ошибку (она не будет, если она маскирует глобальную переменную, но сама по себе является сомнительной практикой).

В качестве альтернативы вы можете установить эти объекты заново при восстановлении сеанса. Но такая логика по необходимости связана с конкретными задачами.

Наконец, например, IPython already has session saving/restoration logic, так что вам, вероятно, вообще не нужно изобретать колесо.

+0

Можете ли вы уточнить логику сеанса в ipython? Также могу ли я хранить эти изменчивые переменные в базе данных? –

+0

1st: done, 2nd: вы поняли суть сериализации и часть «не имеют смысла как постоянные данные»? –