[Tutor] threading tutorial
Cameron Simpson
cs at zip.com.au
Thu May 25 18:03:59 EDT 2017
On 25May2017 11:52, Michael C <mysecretrobotfactory at gmail.com> wrote:
>Right now all i need is to grab 3 values from 3 variables before killing a
>thread, like this:
>
>def stuff():
> do stuff,
> get values, (x,y,d)
>
># main code
>startthread(stuff(), blah)
># if else need to sleep or kill the thread, and because I'll restart the
>thread later, I'd like to get the values from the thread, say x,y,d in
>order to restart the thread.
>loop.
>
>Therefore, how do I get a few values from a few variables from the thread
>and then close it?
>
>Threading is very new to me, so I have to be very diligent.
You always need to be diligent with threads :-)
Can you explain why you need to use a thread for this? The first cut of your
program looks like you could do it with a ordinary function:
def stuff():
... compute x, y, z ...
return x, y, z
def main():
x, y, z = stuff()
OTOH, your later description suggests that you want to kick off a thread to
work on something, and have your main program let it run, or pause it. The
implication is that x, y, z represent the thread state allowing you to restart
it from scratch at the same point where you paused/stopped things.
There are a few different ways to manage that scenario. But first, write
yourself a small Thread based program to familiarise yourself with threads. For
example (untested):
from __future__ import print_function
from time import sleep
from threading import Thread
def thread_main_body():
print("thread started")
for n in range(20):
print("thread", n)
sleep(0.3)
print("thread done")
def main():
print("main")
T = Thread(target=thread_main_body)
print("main: Thread created but _not_ started")
sleep(1)
T.start()
print("thread started")
for n in range(10):
print("main", n)
sleep(0.4)
print("main program waiting for thread")
T.join()
print("main program done")
You should see the main thread and your subthread outputs interleaved. The
sleeps are just to ensure some interleaving and to give good interactive feel.
It should run for about 8 seconds overall. Make sure you're happy you
understand what is happening, why, and when.
There are a few things you need to keep in mind with threads (in Python, and to
a degree in other languages):
1: You can't kill/stop a Thread. Instead, the usual approach to to share some
state with some kind of "running" flag, a boolean saying that the Thread's
function should continue. Then the thread polls that regularly. Eg, if the
thread function runs a main loop it might look like this:
def fn():
global run_me
while run_me:
... do some work ...
and then elsewhere you go:
global run_me
run_me = True
... create and start the Thread ...
... later ...
run_me = False
T.join()
so effectively you ask the Thread to stop, and it obeys when it notices the
change to "run_me". Using a global for this is pretty crube, and not the
general approach, BTW.
2: Like any other function, the local varaibles to the thread function are not
available outside. Thus the "global" hack above. So to share state you would
usually make some kind of object with the state, and pass it in to the Thread
when you create and start it:
def fn(state):
while state.run_me:
... do stuff, keep important things like results in "state" ...
state.x = 1
state.y = whatever
class State(object):
pass
def main():
state = State()
state.run_me = True
T = Thread(target=fn, args=(state,))
T.start()
for n in range(10):
print("main", n, "x =", state.x, "y =", state.y)
sleep(0.3)
state.run_me = False
T.join()
As I remarked, there are a few ways to approach your scenario. The above should
get you started on one approach. Pausing can be done in a few ways, either by
starting and stopping individual threads, one after another, or by starting one
thread and using a mutex of some kind to cause it to suspend activity when
needed. Yet another approach is corroutines, but I'd recommend getting
threading understood first to avoid confusion.
Come back woith some functioning code and more questions.
Cheers,
Cameron Simpson <cs at zip.com.au>
More information about the Tutor
mailing list