Reputation: 416
i started Python a couple weeks ago in learning purposes. I wonder if it is possible to unlock a semaphore acquire from a specific thread. or is there any other tool ?
import threading, time
sem = threading.Semaphore
def thread1 (threadname):
#Code to do
#Condition thread1
time.sleep(0.001)
sem.acquire()
#Code 1
sem.release
def thread2 (threadname):
while (thread1.is_alive() == True):
if #Condition thread1
sem.acquire()
#Code 2
sem.release
My condition in thread 1 is juste before the time.sleep (so thread 2 has time to block thread1 with the .acquire
). If I don't have that time.sleep
, results are not consistent.
I get the good results now, but I would like my thread 2 to begin its "if" always before thread 1 begins "Code1",so I could delete that time.sleep(0.001)
and get consistent results.
Do you have any idea ?
Upvotes: 2
Views: 682
Reputation: 59536
You ask for a synchronization of the startup behavior. For this, your current use of a semaphore isn't fit. What you coded states clearly that you do not care which process is running first. This also is the standard way of handling things, so if you have the need to have one thread before the other, a different synchronization mechanism probably is needed. I could tell you more if I knew more about your underlying desire.
However, what you want to achieve, based on your current code, would be done using a second mechanism, blocking the first thread before it even tries to acquire the semaphore, and which is released by the second thread once it is inside its critical code block, e. g. a threading.Event
:
#!/usr/bin/env python3
import threading, time
semaphore = threading.Semaphore()
event = threading.Event()
event.clear()
def action1():
print("starting thread1")
time.sleep(0.1)
print("waiting in thread1 ...")
event.wait()
print("woken up in thread1!")
print("acquiring in thread1 ...")
semaphore.acquire()
print("critical in thread 1")
semaphore.release()
print("leaving thread1")
def action2():
print("starting thread2")
while (threads[0].is_alive()):
print("acquiring in thread2 ...")
semaphore.acquire()
print("critical in thread 2")
event.set()
time.sleep(0.1)
semaphore.release()
print("released in thread2")
print("leaving thread2")
threads = [ threading.Thread(target=action1),
threading.Thread(target=action2) ]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
But this seems crude to me an error-prone. If you tell us what you really wanted to achieve, what problem you are trying to solve originally, the answer probably can be improved a lot.
Upvotes: 2