如何在上下文管理器中使用线程?

问题描述 投票:2回答:1

考虑这个threading.Thread类:

class Sleeper(threading.Thread):
    def __init__(self, sleep=5.0):
        threading.Thread.__init__(self)
        self.event = threading.Event()
        self.sleep = sleep

    def run(self):
        while self.sleep > 0 and not self.event.is_set():
            self.event.wait(1.0)
            self.sleep -= 1

    def stop(self):
        self.event.set()

它会睡眠一段时间并在达到该数量之前退出或停止。

我用它作为:

sleeper = Sleeper()
try:
    sleeper.start()
    # do stuffs here
except:
    # handle possible exceptions here
finally:
    sleeper.stop()

我宁愿像上下文管理器一样使用它:

with Sleeper():
    # do stuffs here

然后在退出with块时停止线程。

我尝试添加__enter____exit__方法,它似乎工作,但我不确定这是要走的路:

def __enter__(self):
    self.start()
    return self

def __exit__(self, type, value, traceback):
    self.stop()

但我真的不确定我在这里做什么。怎么做得恰到好处?

python python-multithreading contextmanager
1个回答
2
投票

即使不太了解你的问题,由于你的aws相关问题缺乏背景。就像你提到的那样,使用上下文来做这件事是可行的。

import threading
import time


class Sleeper(threading.Thread):
    def __init__(self, sleep=5.0):
        threading.Thread.__init__(self, name='Sleeper')
        self.stop_event = threading.Event()
        self.sleep = sleep

    def run(self):
        print('Thread {thread} started'.format(thread=threading.current_thread()))
        while self.sleep > 0 and not self.stop_event.is_set():
            time.sleep(1.0)
            self.sleep -= 1
        print('Thread {thread} ended'.format(thread=threading.current_thread()))

    def stop(self):
        self.stop_event.set()

    def __enter__(self):
        self.start()
        return self

    def __exit__(self, *args, **kwargs):
        self.stop()
        print('Force set Thread Sleeper stop_event')


with Sleeper(sleep=2.0) as sleeper:
    time.sleep(5)

print('Main Thread ends')

你可以测试这两种情况:1。主睡眠时间更长,2。睡眠者线程有更大的睡眠参数,它们最终会得到两个结果;

如果你仍然想与主要的Sleeper线程进行交互,你的代码应如下所示:

with Sleeper(sleep=2.0) as sleeper:
    cnt = 15

    while cnt > 0 and sleeper.is_alive():
        print(cnt)
        cnt -= 1
        time.sleep(1)

并且您可以看到主要只打印一些数字,因为睡眠者已经结束并且不再活着。

© www.soinside.com 2019 - 2024. All rights reserved.