[Tutor] threading tutorial

Michael C mysecretrobotfactory at gmail.com
Thu May 25 22:47:09 EDT 2017


message received, i ll take a look tomorrow asap.

thanks for replying!!!

On Thu, May 25, 2017 at 3:03 PM, Cameron Simpson <cs at zip.com.au> wrote:

> 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