Python threading - значение часового или событие для разрыва циклов - PullRequest
0 голосов
/ 29 мая 2018

Я могу придумать два способа выхода из цикла в потоке Python, минимальные примеры приведены ниже:

1 - использовать значение часового

from threading import Thread, Event
from time import sleep

class SimpleClass():

    def do_something(self):
        while self.sentinel:
            sleep(1)
            print('loop completed')

    def start_thread(self):
        self.sentinel = True
        self.th = Thread(target=self.do_something)
        self.th.start()

    def stop_thread(self):
        self.sentinel = False
        self.th.join()

simpleinstance = SimpleClass()
simpleinstance.start_thread()
sleep(5)
simpleinstance.stop_thread()

2 - использовать событие

from threading import Thread, Event
from time import sleep

class SimpleThread(Thread):

    def __init__(self):
        super(SimpleThread, self).__init__()

        self.stoprequest = Event()

    def run(self):
        while not self.stoprequest.isSet():
            sleep(1)
            print('loop completed')

    def join(self, timeout=None):
        self.stoprequest.set()
        super(SimpleThread, self).join(timeout)

simpleinstance = SimpleThread()
simpleinstance.start()
sleep(5)
simpleinstance.join()

В документации по Python обсуждаются события, но не более простой подход «значение часового» (который, как я вижу, используется во многих многопоточных ответах при переполнении стека)).

Есть ли какой-либо недостаток в использовании значения часового?

В частности, может ли это привести к ошибкам (у меня никогда не было таких, но я представляю, пытались ли вы изменить значениеСтража в тот же момент, когда он читался для цикла while, тогда что-то могло прерваться (или, возможно, CPython GIL спас бы меня в этом случае). Что считается лучшей (самой безопасной) практикой?

1 Ответ

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

Если вы посмотрите на источник Event, вы увидите, что функция, которую вы используете, больше не имеет значения для вас:

class Event:
    def __init__(self):
        self._cond = Condition(Lock())
        self._flag = False

    def is_set(self):
        return self._flag

    def set(self):
        with self._cond:
            self._flag = True
            self._cond.notify_all() # No more-value, because you are not using Event.wait

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

События полезны, только если вы используете их waitспособ.

...