jlengrand jlengrand - 10 days ago 6
Python Question

Python threads and Lock : Deadlock

I am trying to use locks to write and read data in threads but have a deadlock I can't solve :s.

Here is the thing. For a reason that is not useful in my problem, I have to start a thread that will itself start other threads.
So I have :
main
-> send_gps_data
-> stream_session

I write in gpsData in stream_session, in an infinite loop (a new report is outputted every second).
I want to read those data in my main.
To avoid data corruption I want to use a blocking lock.

Here is the code :

def main():
lock = threading.Lock()
thread_gps = threading.Thread(None, send_gps_data, args=(gpsData, lock))
gps_thread_gps.start()

# to allow interrupt
while(gm.runn):
try:
time.sleep(0.5)
print "!"
lock.acquire():
gm.display_gpsdata(gpsData)
lock.release()
print "!!"
except KeyboardInterrupt:
gm.runn = 0

def send_gps_data(gpsData, lock):
global runn
gps_thread = threading.Thread(None, stream_session, args=(gpsData, lock))
gps_thread.start()
while(runn):
time.sleep(1)
gps_thread._Thread__stop()
sys.exit(0)

def stream_session(gpsData, session, lock):
for report in session:
if report.get("class") == "TPV":
print ":"
lock.acquire()
fill_gpsdata(gpsData, session, report)
lock.release
print "::"


My problem is that I end up with a deadlock. Here is the output I get with the code :
!
!!
!
!!
:
::
!
:

And there it blocks. . .
So it seems like my lock release is never taken into account. . .

I tried to create lock as a global variable, but it doesn't change anything.

Could you please help me on this? I really don't see the problem

Answer

try with calling the lock.release method :

def stream_session(gpsData, session, lock):
    for report in session:
        if report.get("class") == "TPV":
            print ":"
            lock.acquire()
            fill_gpsdata(gpsData, session, report)
            lock.release()   # better to call the method
            print "::"

And to answer to :

So it seems like my lock release is never taken into account. . .

yes, it will ignore the release of the lock, because you don't release it :) .