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

      

+3


source to share


4 answers


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.

+6


source


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

.

+4


source


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.

+2


source


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.

+1


source







All Articles