首页 > 解决方案 > 尝试运行 2 个阻塞函数时与 ThreadPoolExecutor 发生死锁

问题描述

我正在尝试运行 2 个不同的阻塞函数,它们使用相同的全局变量a

编码:

from concurrent.futures import ThreadPoolExecutor, as_completed
import keyboard

a = 0

def incA():
    global a
    while True:
        print(f'inc a: {a} -> {a+1}')
        a+=1
        if keyboard.is_pressed('q'):  # if key 'q' is pressed 
            break
        
        
def printA():
    # a is read-only
    while True:
        print(f'print a: {a}')
        if keyboard.is_pressed('q'):  # if key 'q' is pressed 
            break
        
        
with ThreadPoolExecutor(max_workers=2) as executor:
    f1 = executor.submit(incA())
    f2 = executor.submit(printA())

当我尝试运行这段代码时,我得到一个deadlock. 输出:

inc a: 15640 -> 15641
inc a: 15641 -> 15642
inc a: 15642 -> 15643
inc a: 15643 -> 15644
inc a: 15644 -> 15645
inc a: 15645 -> 15646
inc a: 15646 -> 15647
inc a: 15647 -> 15648
inc a: 15648 -> 15649
inc a: 15649 -> 15650
inc a: 15650 -> 15651
inc a: 15651 -> 15652
inc a: 15652 -> 15653
print a: 15653  

如何解决此问题以使我的代码异步运行,以使其具有如下所示的输出:

.
.
.
inc a: 15640 -> 15641
print a: 15641
inc a: 15641 -> 15642
print a: 15642
inc a: 15642 -> 15643
print a: 15643
.
.
.

标签: pythonmultithreadingthreadpooldeadlock

解决方案


当您调用 时submit,您将在函数中包含括号:

f1 = executor.submit(incA())
f2 = executor.submit(printA())

因此,您不是传递函数对象,而是执行一次函数并传递结果,除非它incA()永远不会返回,因此您实际上永远不会提交任何东西。

只需删除括号:

f1 = executor.submit(incA)
f2 = executor.submit(printA)

推荐阅读