ThreadPoolExcutor starvation



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

代码:

from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
import keyboard
a = 0
def incA():
global a

while True:
print(f'inc a: {a} -> {a+1}', end = 'n')
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}', end = 'n')
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)

所需输出:

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

该代码的给定输出是:

print a: 1428inc a: 1429 -> 1430
print a: 1429
inc a: 1430 -> 1431print a: 1430
inc a: 1431 -> 1432print a: 1431
inc a: 1432 -> 1433print a: 1432
inc a: 1433 -> 1434print a: 1433
inc a: 1434 -> 1435print a: 1434
inc a: 1435 -> 1436print a: 1435
inc a: 1436 -> 1437print a: 1436

这与我想要的很接近,但正如你所看到的,打印的一些结尾(不要与printA函数混淆(被剪掉了,尽管我明确地将end='n'放在了函数中。


我试图给系统添加一个锁,但它导致了饥饿。在每个函数的while True循环中,我添加了以下行:

def printA():
global lock 
# a is read-only

while True:
try:
lock.acquire()
print(f'print a: {a}', end = 'n')
if keyboard.is_pressed('q'):  # if key 'q' is pressed 
break
finally:
lock.release()

导致这种输出(饥饿(的原因:

inc a: 1319 -> 1320
inc a: 1320 -> 1321
inc a: 1321 -> 1322
inc a: 1322 -> 1323
inc a: 1323 -> 1324
inc a: 1324 -> 1325
print a: 1325
print a: 1325
print a: 1325
print a: 1325
print a: 1325
print a: 1325

使用Ron Serruya建议的链接打印跳过换行符的答案,我们将换行符添加到消息中以防止分离。

修改后的代码

from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
import keyboard
a = 0
def incA():
global a

while True:
print(f'inc a: {a} -> {a+1}n', end = '')  # Place newline in message to prevent separation
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}n', end = '') # Place newline in message to prevent separation
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)

输出

...
inc a: 3459 -> 3460
print a: 3459
print a: 3459
inc a: 3460 -> 3461
print a: 3460
inc a: 3461 -> 3462
print a: 3461
inc a: 3462 -> 3463
inc a: 3463 -> 3464
print a: 3463
inc a: 3464 -> 3465
print a: 3464
inc a: 3465 -> 3466
print a: 3465
inc a: 3466 -> 3467
print a: 3466
...

相关内容

  • 没有找到相关文章

最新更新