[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.
>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)
    print("thread done")

  def main():
    T = Thread(target=thread_main_body)
    print("main: Thread created but _not_ started")
    print("thread started")
    for n in range(10):
      print("main", n)
    print("main program waiting for thread")
    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

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):

  def main():
    state = State()
    state.run_me = True
    T = Thread(target=fn, args=(state,))
    for n in range(10):
      print("main", n, "x =", state.x, "y =", state.y)
    state.run_me = False

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.

Cameron Simpson <cs at zip.com.au>

More information about the Tutor mailing list