ρss
ρss

Reputation: 5315

Confusion regarding the output of threads in python

I am currently working with python v.2.7 on windows 8.

My programme is using threads. I am providing a name to these threads during their creation. The first thread is named First-Thread and second one is named Second-Thread. The threads execute a method named as getData() that does the following:

The compareValues() does the following:

I save the results of these threads to a list named as myList and then finally print this myList.

Problem: Why I never see the Second-Thread in myList? I don't understand this behavior. Please try to execute this code to see the output in order to understand my problem.

Code:

import time
from random import randrange
import threading

myList = []
def getData(i):
        print "Sleep for %d"%i
        time.sleep(i)
        data = compareValues()
        for d in list(data):
            myList.append(d)

def compareValues():
        number = randrange(10)
        if number >= 5:
             yield "%s: Greater than or equal to 5: %d  "%(t.name, number)
        else:
             yield "%s: Less than 5: %d  "%(t.name, number)

threadList = []
wait = randrange(10)+1
t = threading.Thread(name = 'First-Thread', target = getData, args=(wait,))
threadList.append(t)
t.start()
wait = randrange(3)+1
t = threading.Thread(name = 'Second-Thread', target = getData, args=(wait,))
threadList.append(t)
t.start()
for t in threadList:
    t.join()
print
print "The final list"
print myList

Sample output:

Sleep for 4Sleep for 1

The final list
['First-Thread: Greater than or equal to 5: 7  ', 'First-Thread: Greater than or equal to 5: 8  ']

Thank you for your time.

Upvotes: 1

Views: 48

Answers (1)

unutbu
unutbu

Reputation: 879083

def compareValues():
        number = randrange(10)
        if number >= 5:
             yield "%s: Greater than or equal to 5: %d  "%(t.name, number)
        else:
             yield "%s: Less than 5: %d  "%(t.name, number)

In the body of compareValues the code refers to t.name. By the time compareValues() gets called by the threads, t, which is looked up according to the LEGB rule and found in the global scope, references the first thread because the t.join() is waiting on the first thread. t.name thus has the value First-Thread.

To get the current thread name, use threading.current_thread().name:

def compareValues():
        number = randrange(10)
        name = threading.current_thread().name
        if number >= 5:
             yield "%s: Greater than or equal to 5: %d  "%(name, number)
        else:
             yield "%s: Less than 5: %d  "%(name, number)

Then you will get output like

Sleep for 4
Sleep for 2

The final list
['Second-Thread: Less than 5: 3  ', 'First-Thread: Greater than or equal to 5: 5  ']

Upvotes: 1

Related Questions