#1
  1. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154

    thread.start_new


    I just started using the thread modules start_new() function and I'm a bit confused on how it should work and how it does work. For instance, the following code:

    Code:
    >>> for i in range(1):
    	start_new(func1, ('000',))
    	func2('111')
    	start_new(func3, ('000',))
    	
    2828
    111
     000
    1476
    000
    
    >>>
    Someone inexperienced with the function would think that the return values would be something like:

    Code:
    000
    111
    000
    However I get 5 return values, not 3. Also, instead of 000, 111, 000 like I would hope to see. It it completely different. Plus the two other "random" values. Can anyone please explain more in detail how this (start_new()) works and why these values get returned in the order they do? Any help is appreciated.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    Well, the first part is explained in the help for thread.start_new_thread (which is the same as thread.start_new):

    start_new(...)
    start_new_thread(function, args[, kwargs])
    (start_new() is an obsolete synonym)

    Start a new thread and return its identifier. [...]
    So the 2828 and 1476 are the identifiers of the two threads.

    They would vanish if you changed the code lines from:

    Code:
    start_new(func1, ('000',))
    
    to
    
    thread1 = start_new(func1, ('000',))
    (and thread2 = ...)

    The second question: " why these values get returned in the order they do?" is to do with the nature of threads.

    Normally, standard ('procedural') code runs from the top, down through the code, following function calls until the code finishes.

    Code:
    a
    ...
    b
    ...
    c
    >>>--->>> vvv
               a
    vvv<<<---<<<
    ...
    b
    ...
    c
    ...
    d
    ...
    end
    Which is fine for some apps, but it's no good if you want to do two things at once.

    Let's say you are drawing fish on the screen, and they are swimming about. You also want to wait for the user to press "enter" and then finish.

    If you write:

    Code:
    draw_fish()
    get_keypresses()
    draw_fish():
    The fish will move once, then stop while the whole computer waits for the user to press a key. They wont be animated, they will be frozen.

    So you get threads, which run two or more lots of "a...b...c" code at the same time, next to each other:

    Code:
    # Thread 1
    flag = False                 |   # Thread 2 
                                 |
    while not flag:              |    while True:
        draw_fish()              |        keypress = read_keys()
        sleep(0.1)               |        if keypress == keys.ENTER:
        draw_fish()              |        flag = True
        sleep(0.2)               |        sleep(0.2)

    So the fish will be moving and animated, and the system will be waiting for the user, both at the same time.

    So your a...b...c code:
    Code:
    print "000"
    print "111"
    print "000"
    is now doing three things at once:

    print 000 in a new thread
    print 111 in the interpreter thread
    print 000 in another new thread.

    Threads run at the 'same time' as each other.
    Except they don't really, because a CPU can only do one thing at once - it just does it blindingly quickly and we humans can't tell the difference.

    So your threads all say "RUN ME! RUN ME! RUN ME!", they settle in random order, and happen.

    Output arrives as it happens, which is completely down to luck, and scheduling algorithms deep in Windows and Python.

    They wont always be in the right order - they wont always be in the same order each time. (Well, they might be, but it's not guaranteed - you can't rely on it).

    (Incidentally, this is why there can be big problems with threaded code - if you have two threads, both reading and writing the to the same place - a list or whatever - it can be quite easy to get them both stuck - sometimes the code will work fine, and sometimes it will lock up. Then you stare at it for ages, and realise that one thread gets lucky every few hours and writes twice in a row before the other one writes anything, then the data structure gets into a state you didn't think it ever could, and both threads crash...)

    Comments on this post

    • Yegg` agrees
    Last edited by sfb; September 5th, 2005 at 06:17 PM.
  4. #3
  5. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154
    Thanks for the very descriptive and detailed explanation sfb. I understand this much better now. Luckily in my case the threads are only being used one at a time, and they are handling requests from other clients (through sockets), so order won't really matter. Thanks again.

IMN logo majestic logo threadwatch logo seochat tools logo