Why do these 10 streams always output the same stream name?
I ran this code
NUM = 0
def count():
global NUM
NUM += 1
time.sleep(1)
print(t.getName()+":"+"NUM is "+str(NUM))
for i in range(10):
t = threading.Thread(target=count)
t.start()
Output signal
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
Thread-10:NUM is 10
I know why NUM is always 10, but why is the thread name always the same? Every thread is running print(t.getName()+":"+"NUM is "+str(NUM))
; t
shouldn't it be a thread that gets cpu time? I think the name shouldn't be the same.
When I changed this to
NUM = 0
def count():
global NUM
NUM += 1
name = t.getName()
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
for i in range(10):
t = threading.Thread(target=count)
t.start()
It works as I expect:
Thread-1:NUM is 10
Thread-3:NUM is 10
Thread-2:NUM is 10
Thread-4:NUM is 10
Thread-5:NUM is 10
Thread-7:NUM is 10
Thread-10:NUM is 10
Thread-9:NUM is 10
Thread-6:NUM is 10
Thread-8:NUM is 10
source to share
This is because you are referencing the global name t
. By the time the sleep ends, the end of the cycle ends and t
remains associated with the last thread (thread 10) created by the cycle.
In your alternative, the results are not actually defined. There you refer to the global t
while the loop is still running, so it can be tied to the most recently created thread, but not necessarily.
Note. If you don't have convenient access to the current thread object, you can use
threading.currentThread()
to get it. Then
threading.currentThread().getName()
will return the name of the thread running it.
source to share
Your functions are requested t
, but no t
is defined in the function :
def count():
global NUM
NUM += 1
name = t.getName() # use outer t
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
Thus, the fallback Python engine will search t
in the direct outer scope. Indeed, you are assigning t
in the outer scope, which is why it takes that value.
Now when you write in a loop , this one changes quickly. It is highly likely that the loop has already reached the last value - especially due to Python's streaming mechanism - before the first thread actually chooses . As a result, all streams are retrieved by referencing the last configured stream. t = ...
for
t
for
t
t
If we, however, rewrite the function :
NUM = 0
def count():
name = t.getName() # t fetched immediately
global NUM
NUM += 1
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
I get:
Thread-11:NUM is 10
Thread-12:NUM is 10
Thread-13:NUM is 10
Thread-14:NUM is 10
Thread-15:NUM is 10
Thread-17:NUM is 10
Thread-16:NUM is 10
Thread-19:NUM is 10
Thread-18:NUM is 10
Thread-10:NUM is 10
on my machine. Of course, this does not guarantee that each thread will capture the correct thread, as it is possible that only later in the process the thread will start running and retrieve the variable t
.
source to share
You have the same problem for both the thread name and count NUM
: by the time you get to the first statement print
, all 10 threads have been started. You only have one global variable t
for the thread and one global NUM
for the count. Thus, all you see is the last value that is for the 10th thread. If you want the individual values ββto be printed, you need to provide your code to the engine to communicate this at startup, or to store a list through which you can iterate.
source to share
I advise you to try the following:
NUM = 0
def count():
global NUM
NUM += 1
num = NUM
name = t.getName()
time.sleep(1)
print("t.getName: " + t.getName() + ", name: " + name + ":" + ", NUM: " + str(NUM) + ", num: " + str(num))
for i in range(10):
t = threading.Thread(target=count)
t.start()
Result:
t.getName: Thread-10, name: Thread-10:, NUM: 10, num: 10
t.getName: Thread-10, name: Thread-6:, NUM: 10, num: 6
t.getName: Thread-10, name: Thread-3:, NUM: 10, num: 3
t.getName: Thread-10, name: Thread-5:, NUM: 10, num: 5
t.getName: Thread-10, name: Thread-4:, NUM: 10, num: 4
t.getName: Thread-10, name: Thread-9:, NUM: 10, num: 9
t.getName: Thread-10, name: Thread-7:, NUM: 10, num: 7
t.getName: Thread-10, name: Thread-2:, NUM: 10, num: 2
t.getName: Thread-10, name: Thread-1:, NUM: 10, num: 1
t.getName: Thread-10, name: Thread-8:, NUM: 10, num: 8
t.getName () - function call, which is a link. By the time the print functions have reached the console, it t
refers to the last thread.
source to share