Reputation: 223
I want to pause a thread in python when another function is called. In the code below, f2
is of higher priority, and f1
should wait until it completes. After reading this post I tried this:
import threading
import time
class c:
def f1():
for j in range(7):
print ("f1")
time.sleep(0.5)
def f2():
with lock:
for i in range(3):
print(i)
time.sleep(1)
lock = threading.Lock()
threading.Thread(target=c.f1).start()
f2()
but the result is this
f1
0
f1
1
f1
f1
2
f1
f1
f1
while the expected output should be this
f1
0
1
2
f1
f1
f1
f1
f1
f1
What is going wrong?
If I add with lock
inside f1
before or after the for
I get this result
f1
f1
f1
f1
f1
f1
f1
0
1
2
which is equally undesirable.
Also please note that the code structure is important. If you offer a solution please keep the same structure, meaning function f1
inside class c
and the rest in the global scope. Only one thread is created in total.
Thank you
Upvotes: 0
Views: 117
Reputation: 12205
Your problem is that you use the lock in only one place - which means it does not lock anything. You should also acquire the lock in f1.
Consider this version of your code:
import threading
import time
class c:
def f1():
for j in range(7):
with lock:
print ("f1")
time.sleep(0.5)
def f2():
with lock:
for i in range(3):
print(i)
time.sleep(1)
lock = threading.Lock()
threading.Thread(target=c.f1).start()
f2()
Now we force f1 to stop and wait for the lock if f2 already has obtained it. Is this what you tried to achieve?
Of course without sleep statements the result can be whatever - there is no guarantee how many times your f1 manages to execute before f2 kicks in and obtains the lock for the entirety of its loop.
This becomes more complicated if both f1 and f2 are "heavy" functions and you want to signal from f2 anytime without delay to f1 "stop doing what you are doing right now". Locks might work if there is a loop but if there was for example a lengthy IO call in process, it would need to complete before f1 released the lock for f2, which means f2 would block in this case.
Without knowing the exact case this is just speculation.
Upvotes: 2