Python threads and atomic operations
我想用同步
我见过这样的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Thread1: def __init__(self): self._stop_event = threading.Event() self._thread = None def start(self): self._thread = threading.Thread(target=self._run) self._thread.start() def stop(self): self._stop_event.set() self._thread.join() def _run(self): while not self._stop_event.is_set(): self._work() def _work(self): print("working") |
但我已经读到原子操作是线程安全的,在我看来,它可以在没有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Thread2: def __init__(self): self._working = False self._thread = None def start(self): self._working = True self._thread = threading.Thread(target=self._run) self._thread.start() def stop(self): self._working = False self._thread.join() def _run(self): while self._working: self._work() def _work(self): print("working") |
它认为类似的实现在C中是不正确的,因为编译器可以将
这里有一个更全面的解决方案,如果工作线程有时需要延迟,也可以使用它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class Worker(threading.Thread): quit = False def __init__(self, ...): super().__init__() self.cond = threading.Condition() ... def delay(self, seconds): deadline = time.monotonic() + seconds with self.cond: if self.quit: raise SystemExit() if time.monotinic() >= deadline: return self.cond.wait(time.monotonic() - deadline) def run(self): while not self.quit: # work here ... # when delay is needed self.delay(123) def terminate(self): with self.cond: self.quit = True self.cond.notify_all() self.join() |
使用方法如下:
1 2 3 4 5 | worker = Worker() worker.start() ... # finally worker.terminate() |
当然,如果您知道工作人员从不睡觉,那么您可以删除
据我所知,它在python中也是不正确的,因为
好吧,让我们说,在多线程的世界里,你不应该真的问:为什么这不应该起作用,而应该问为什么这被保证起作用。
在大多数情况下,多线程在cpython中要容易一些,因为gil保证:
- 在任何给定时间只执行一个解释器命令。
- 强制线程之间的内存同步。
请记住,gil是一个实现细节,如果有人不使用它重写cpython,这可能会消失。
还要注意的是,它应该以这种方式在任何实际系统中实现它。