在Python中为任务锁定线程
我有一个程序,一旦达到某个阈值,就使用线程启动另一个线程。现在,第二个线程正在多次启动。我实现了一个锁,但我认为我做得不对在Python中为任务锁定线程,python,multithreading,Python,Multithreading,我有一个程序,一旦达到某个阈值,就使用线程启动另一个线程。现在,第二个线程正在多次启动。我实现了一个锁,但我认为我做得不对 for i in range(max_threads): t1 = Thread(target=grab_queue) t1.start() 在抓取队列中,我有: 它启动另一个线程来处理行列表。我想确保一旦它达到if条件,其他线程就不会运行,以确保处理行列表的额外线程不会启动 您的锁覆盖了错误的代码部分。在检查行的大小和重置行的代码部分之间存在竞争条件。
for i in range(max_threads):
t1 = Thread(target=grab_queue)
t1.start()
在抓取队列中,我有:
它启动另一个线程来处理行列表。我想确保一旦它达到if条件,其他线程就不会运行,以确保处理行列表的额外线程不会启动 您的锁覆盖了错误的代码部分。在检查行的大小和重置行的代码部分之间存在竞争条件。由于锁仅在大小检查之后才被获取,因此两个线程可以很容易地同时确定数组已变得过大,并且只有到那时锁才会开始序列化数组的重置。在这种情况下,“序列化”意味着任务仍将执行两次,每个线程执行一次,但它将连续执行,而不是并行执行 正确的代码可能如下所示:
rows.append(resultJson)
with grow_lock:
if len(rows.value()) >= 250:
row_thread = Thread(target=insert_rows, kwargs={'rows': rows.value()})
row_thread.start()
rows.reset()
问题中显示的代码还有另一个问题:如果Lock()
指的是threading.Lock
,那么它会在每次调用和每个线程中创建并锁定一个新锁!锁保护线程之间共享的资源,要执行该功能,锁本身必须共享。要解决此问题,请实例化锁一次并将其传递给线程的目标函数
退一步,代码实现了一个自定义线程池。要做到这一点并涵盖所有关键案例需要大量的工作、测试和调试。有一些经过生产测试的模块专门用于此目的,例如Python附带的
多处理
模块(它支持进程池和线程池),在重新实现它们的功能之前,最好先了解它们。例如,有关基于多处理的线程池的可访问介绍,请参见。您的锁覆盖了错误的代码部分。在检查行的大小和重置行的代码部分之间存在竞争条件。由于锁仅在大小检查之后才被获取,因此两个线程可以很容易地同时确定数组已变得过大,并且只有到那时锁才会开始序列化数组的重置。在这种情况下,“序列化”意味着任务仍将执行两次,每个线程执行一次,但它将连续执行,而不是并行执行
正确的代码可能如下所示:
rows.append(resultJson)
with grow_lock:
if len(rows.value()) >= 250:
row_thread = Thread(target=insert_rows, kwargs={'rows': rows.value()})
row_thread.start()
rows.reset()
问题中显示的代码还有另一个问题:如果Lock()
指的是threading.Lock
,那么它会在每次调用和每个线程中创建并锁定一个新锁!锁保护线程之间共享的资源,要执行该功能,锁本身必须共享。要解决此问题,请实例化锁一次并将其传递给线程的目标函数
退一步,代码实现了一个自定义线程池。要做到这一点并涵盖所有关键案例需要大量的工作、测试和调试。有一些经过生产测试的模块专门用于此目的,例如Python附带的多处理
模块(它支持进程池和线程池),在重新实现它们的功能之前,最好先了解它们。例如,有关基于多处理的线程池的可访问介绍,请参见。谢谢!你能详细说明一下第二部分吗?我确实在使用threading.lock。你的意思是在我的程序开始时实例化一个锁,并将它作为参数传递给我的线程吗?@Wilson如果你在程序开始时实例化锁,你还可以将它保存在一个全局变量中。理想情况下,可以在创建行的同一位置实例化锁。避免使用全局变量使得不知道彼此的多个线程池可能存在。另外,请了解修正答案中的广告。谢谢!你能详细说明一下第二部分吗?我确实在使用threading.lock。你的意思是在我的程序开始时实例化一个锁,并将它作为参数传递给我的线程吗?@Wilson如果你在程序开始时实例化锁,你还可以将它保存在一个全局变量中。理想情况下,可以在创建行的同一位置实例化锁。避免使用全局变量使得不知道彼此的多个线程池可能存在。另外,了解修正答案中所宣传的。