[PYTHON] Implement a thread that can be paused by exploiting yield

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 inyield`. 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)

No output for 2 seconds

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

Implement a thread that can be paused by exploiting yield
[Python] A program that finds a pair that can be divided by a specified value
How to install a Python library that can be used by pharmaceutical companies
List the classes that can be referenced by ObjCClass
How to create a property of relations that can be prefetch_related by specific conditions
Let's make a diagram that can be clicked with IPython
Convert mesh data exported from SpriteUV2 to a format that can be imported by Spine
[Python] Make a graph that can be moved around with Plotly
Make a Spinbox that can be displayed in Binary with Tkinter
A timer (ticker) that can be used in the field (can be used anywhere)
I made a shuffle that can be reset (reverted) with Python
Make a Spinbox that can be displayed in HEX with Tkinter
Make a currency chart that can be moved around with Plotly (1)
Can I be a data scientist?
"Obake" can be sung by "you"
Confirmation that rkhunter can be installed
I created a template for a Python project that can be used universally
Hide the warning that zsh can be used by default on Mac
How to make a rock-paper-scissors bot that can be easily moved (commentary)
Draw a graph that can be moved around with HoloViews and Bokeh
I made a simple timer that can be started from the terminal
A story that heroku that can be done in 5 minutes actually took 3 days
A memo for making a figure that can be posted to a journal with matplotlib
A class for PYTHON that can be operated without being aware of LDAP
I want to create a priority queue that can be updated in Python (2.7)
A personal memo of Pandas related operations that can be used in practice
Format DataFrame data with Pytorch into a form that can be trained with NN
I made a familiar function that can be used in statistics with Python
Read the image posted by flask so that it can be handled by opencv
[Hackathon] About making a tool that can be CD on Raspberry Pi [Convenient tool]
"Gazpacho", a scraping module that can be used more easily than Beautiful Soup