Suppose you have an ordinary subroutine
def foo():
print("foo")
print("bar")
foo () # Output "foo" and "bar"
Divide by inserting yield
in this
def foo():
print("foo")
yield 0
print("bar")
yield 0
f = foo()
f.next () # Output "foo" f.next () # Output "bar"
In other words, make one process an iterator with yield
If you apply this to Thread
, you can implement pause / resume / suspend (pause / resume / halt
method).
class Shred(Thread):
def __init__(actions):
Thread.__init__()
self._actions = actions
self.is_halted = False
self.is_paused = False
def run():
while True:
if self.is_paused:
continue
if self.is_halted:
return
try:
self._actions.__next__()
except StopIteration:
self.is_halted = True
return
def pause():
self.is_paused = True
def resume():
self.is_paused = False
def halt():
self.is_halted = True
(Actually it is better to use ʻEventfor the flag) This allows the pause / resume / suspend chokepoints to be represented only in
yield`.
In addition to improving readability, you can focus on writing other logic
def baz():
for n in range(10):
print(n)
time.sleep(1)
yield 0
s = Shred(baz())
s.start()
time.sleep(2)
# 0
# 1
# 2
s.pause()
time.sleep(2)
s.resume()
time.sleep(2)
# 3
# 4
# 5
s.halt()
#End of output
By the way, this iterator will return to the original subroutine after executing all the contents.
list(baz())
# 0
# 1
# 2
# ...
# 9
I came up with the idea, but I didn't actually use it for the following reasons.
--Maximum surprise ――Mostly it will be implemented normally later ――It is discouraging to actively utilize side effects ――I feel like I'm playing with the language and I'm angry ――I mean, no one is hitting such a low-level API these days.
So I don't know how helpful it is, but that's it
Recommended Posts