Python:线程

Python:线程,python,multithreading,Python,Multithreading,我想多次启动线程,但只在线程未运行时启动。 我正在尝试的是一个简单的模型: import threading import time def up (x, r): time.sleep(3) r['h'] = x + 1 hum = {'h' : 0} while True: print(hum['h']) H = threading.Thread(target = up, args=(hum['h'],hum)) H.daemon=True

我想多次启动线程,但只在线程未运行时启动。 我正在尝试的是一个简单的模型:

import threading 
import time


def up (x, r):
    time.sleep(3)
    r['h'] = x + 1


hum = {'h' : 0}

while True:
    print(hum['h'])
    H = threading.Thread(target = up, args=(hum['h'],hum))
    H.daemon=True
    if not H.isAlive():
        H.start()
    print(threading.active_count())
我也不明白的是: 当我运行程序时,它会打印:0。然后在3秒后打印:1,依此类推,每3秒增加1。 但我想它会打印:0。然后在3秒钟后,它会打印:1。然后立即快速增长。 因为在启动第一个线程后,它会立即启动下一个线程,依此类推。为什么会发生这种情况?
如果线程已经在运行,如何不启动它

代码中发生了什么:

  • 打印
    hum['h']
  • 创建一个线程(注意,您创建了它,但还没有启动它)
  • 设置属性的值
  • 如果线程未启动,则启动它
  • 打印活动线程的计数(活动,未启动)
由于每次都替换
H
变量,因此每次都会有一个新线程立即启动

如果为处于活动状态的添加一个在If中显示“starting”的打印,您将看到每次都会调用它。

您可以使用来等待线程完成:

import threading 
import time


def up (x, r):
    time.sleep(3)
    r['h'] = x + 1


hum = {'h' : 0}

while True:
    print(hum['h'])
    H = threading.Thread(target = up, args=(hum['h'],hum))
    H.daemon=True
    H.start()
    H.join()
    print(threading.active_count())
如果不想等待,可以将当前正在运行的线程保存在一个变量中,并在循环中检查它:

import threading 
import time


def up (x, r):
    time.sleep(3)
    r['h'] = x + 1


hum = {'h' : 0}

current_thread = None

while True:
    print(hum['h'])
    if current_thread is None:
        current_thread = threading.Thread(target = up, args=(hum['h'],hum))
        current_thread.daemon=True
        current_thread.start()
    elif not current_thread.isAlive():
        current_thread = threading.Thread(target = up, args=(hum['h'],hum))
        current_thread.daemon=True
        current_thread.start()

不确定我是否完全理解了你的问题,但这里有一些想法。 当我运行你的代码时,我得到了越来越多的活动线程,因为你每次都在创建一个新线程,检查它的状态(总是
不活动
),然后启动它。 相反,您要做的是检查上次运行线程的状态,如果该线程不活动,则启动一个新线程。为此,如果旧线程已完成,则应创建新线程:

def up (x, r):
    time.sleep(3)
    r['h'] = x + 1


def main():
    hum = {'h' : 0}
    H = threading.Thread(target = up, args=(hum['h'],hum))
    H.daemon=True

    while True:
        # print(hum['h'])
        if not H.isAlive():
            H = threading.Thread(target = up, args=(hum['h'],hum))
            H.daemon=True
            H.start()
            print(threading.active_count())

您没有得到
运行时错误:无法启动新线程
?我尝试运行您的代码,但没有得到您解释的内容…相反,我得到的线程数量迅速增加,因为您每次都在创建不同的实例。你能更好地解释一下你所看到的和你期望的吗?如果你把线程实例的定义移出while循环,你会得到一个
运行时错误:不能像@GyuHyeon Choi建议的那样启动新线程
。@toti08我在spyder中运行代码,也会得到快速增加的线程实例,但“哼哼”增长缓慢,我不知道为什么?@toti08在这里,我可以将线程定义移出while循环。但如果存在这样的情况,即参数在while循环内发生变化,那么在while循环外定义它是没有意义的。我尝试过,并且了解发生了什么,但如何使事情正常工作。如何检查旧线程(未替换)是否处于活动状态?我不想等待。我想在h更改时不断打印。这是我想要的,但我仍然不明白当有大量正在运行的线程时,为什么它们不同时增加h。就像当一个线程启动时,在下一次迭代中,第二个线程立即启动。然后在3秒钟后,第一个线程增加了h 1,但在第二个线程也完成了睡眠,增加了h 1。我不知道如何解释我想说的。那是因为当你启动一个线程时,你会在那一刻传递
hum
的值,而
hum['h']
只会在第一个线程启动后3秒增加。如果同时启动其他线程,它们将收到
0
作为
x
参数,因此它们将用1(x+1)替换
hum[h]
。这不是理想的情况,这是你可能想要避免的,因为这很难控制。现在我明白了。这是我必须使用锁的情况。