Reputation: 35
I'm trying to run 2 different blocking functions, that utilize the same global variable 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
.
.
.
the given output for this code is this:
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
which is close to what I want, but as you can see, some of the ending of the prints (not to be confused with the printA
function) gets cut off, even though I explicitly put end='\n'
in the funciton.
I tried to add a Lock to the system, but it resulted in starvation. Inside the while True
loop of each function, I added those lines:
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()
Which resulted in this output (starvation):
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
Upvotes: 0
Views: 107
Reputation: 17176
Using the answer from Ron Serruya suggested link Print skipping newline we add the newline to the message to prevent separation.
Modified Code
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)
Output
...
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
...
Upvotes: 1