Как правильно обеспечить завершение потока, который использует общую блокировку? - PullRequest
0 голосов
/ 30 мая 2018

В __main__ я создаю новый поток демона для обеспечения неблокирующей обработки в общем состоянии, защищенном threading.Lock().Несмотря на то, что все работает нормально, когда программа запущена, время от времени я получаю исключение при выходе из программы, т.е. когда предполагается, что поток демона завершается:

Объект 'NoneType' не имеетатрибут «приобретать»

Код примерно такой:

mutex = threading.Lock()

def async_processing(shared):
    global mutex
    while True:
        sleep(1)
        mutex.acquire()
        try:
            shared.modify_state()
        finally:
            mutex.release()


if __name__ == '__main__':
    shared = SomeObject()

    thread = threading.Thread(target=async_processing, args=(shared,))
    thread.daemon = True
    thread.start()

    if user_enters_some_command_to_stdin:       
        mutex.acquire()
        try:
            shared.modify_state()
        finally:
            mutex.release()

Я не совсем дома с Python и, таким образом, возможно, я не делаю это так, как он долженбыть готовым, но я предполагаю, что каким-то образом переключение контекста в поток происходит после того, как mutex больше не доступен.Верна ли эта гипотеза?

Как лучше всего справиться с этим?

1 Ответ

0 голосов
/ 30 мая 2018

Я думаю, что самый простой способ - добавить переменную-флаг:

mutex = threading.Lock()
flag = True

def async_processing(shared):
    while flag:
        sleep(1)
        with mutex:
            shared.modify_state()


if __name__ == '__main__':
    shared = SomeObject()

    thread = threading.Thread(target=async_processing, args=(shared,))
    thread.start()

    if some_user_action:        
        with mutex:
            shared.modify_state()
    flag = False
    thread.join()  # wait for exit.
...