为什么这10个线程总是输出相同的线程名?
Why this 10 threads always output the same thread name?
我运行这个代码
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()
输出为
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
我知道为什么NUM总是10,但是为什么线程名总是一样的?每个线程运行print(t.getName()+":"+"NUM is "+str(NUM))
; t
不应该是获得 cpu 时间的线程吗?我觉得名字应该不一样吧
当我改成这个的时候
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()
如我所料:
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
您的函数查询 t
,但 t
未在函数中定义 :
def count():
global NUM
NUM += 1
name = <b>t.</b>getName() # use outer t
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
Python 的回退机制因此将在直接外部范围内寻找 t
。实际上,您在外部范围内分配了一个 t
,因此它将采用该值。
现在,由于您在 for
循环 中编写了 t = ...
,因此 t
变化很快。 for
循环很可能已经达到最后一个值 - 特别是因为 Python 的线程机制 - 在第一个线程实际获取 t
之前。结果,所有线程获取 t
引用 last 构造的线程。
如果我们 将函数重写为 :
NUM = 0
def count():
name = t.getName() # t fetched immediately
global NUM
NUM += 1
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
我得到:
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
在我的机器上。当然,这 not 保证每个线程都会获取 correct 线程,因为有可能只有在进程的后期,线程才会启动工作并获取 t
变量。
线程名称和计数 NUM
都遇到了同样的问题:当您到达第一个 print
语句时,所有 10 个线程都已启动。您只有 one 全局变量 t
用于线程,one 全局变量 NUM
用于计数。因此,您所看到的只是最后一个值,即第 10 个线程的值。如果您想要打印单独的值,您需要为您的代码提供一种机制以在它们启动时报告它们,或者保留一个您可以迭代的列表。
这是因为您引用了全局名称t
。到睡眠结束时,循环结束,t
仍然绑定到循环创建的最后一个线程(第 10 个线程)。
在您的备选方案中,实际上并未定义结果。在那里你引用了全局 t
而 循环仍然是 运行,所以它很可能绑定到最近创建的线程 - 但不是 有。
注意:如果您目前运行没有方便的访问线程对象,可以使用
threading.currentThread()
得到它。那么
threading.currentThread().getName()
将return线程的名称运行吧。
我建议你试试这个:
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()
结果:
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()是函数调用,是引用。当打印功能到达控制台时,t
引用最新线程。
我运行这个代码
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()
输出为
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
我知道为什么NUM总是10,但是为什么线程名总是一样的?每个线程运行print(t.getName()+":"+"NUM is "+str(NUM))
; t
不应该是获得 cpu 时间的线程吗?我觉得名字应该不一样吧
当我改成这个的时候
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()
如我所料:
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
您的函数查询 t
,但 t
未在函数中定义 :
def count():
global NUM
NUM += 1
name = <b>t.</b>getName() # use outer t
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
Python 的回退机制因此将在直接外部范围内寻找 t
。实际上,您在外部范围内分配了一个 t
,因此它将采用该值。
现在,由于您在 for
循环 中编写了 t = ...
,因此 t
变化很快。 for
循环很可能已经达到最后一个值 - 特别是因为 Python 的线程机制 - 在第一个线程实际获取 t
之前。结果,所有线程获取 t
引用 last 构造的线程。
如果我们 将函数重写为 :
NUM = 0
def count():
name = t.getName() # t fetched immediately
global NUM
NUM += 1
time.sleep(1)
print(name+":"+"NUM is "+str(NUM))
我得到:
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
在我的机器上。当然,这 not 保证每个线程都会获取 correct 线程,因为有可能只有在进程的后期,线程才会启动工作并获取 t
变量。
线程名称和计数 NUM
都遇到了同样的问题:当您到达第一个 print
语句时,所有 10 个线程都已启动。您只有 one 全局变量 t
用于线程,one 全局变量 NUM
用于计数。因此,您所看到的只是最后一个值,即第 10 个线程的值。如果您想要打印单独的值,您需要为您的代码提供一种机制以在它们启动时报告它们,或者保留一个您可以迭代的列表。
这是因为您引用了全局名称t
。到睡眠结束时,循环结束,t
仍然绑定到循环创建的最后一个线程(第 10 个线程)。
在您的备选方案中,实际上并未定义结果。在那里你引用了全局 t
而 循环仍然是 运行,所以它很可能绑定到最近创建的线程 - 但不是 有。
注意:如果您目前运行没有方便的访问线程对象,可以使用
threading.currentThread()
得到它。那么
threading.currentThread().getName()
将return线程的名称运行吧。
我建议你试试这个:
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()
结果:
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()是函数调用,是引用。当打印功能到达控制台时,t
引用最新线程。