Thread Safe PDALib solution - perhaps
Posted: Sun Jul 03, 2016 5:12 pm
In addition to commenting out the duplicate digitalWrite(pin,val) definition, I believe I found a solution to make digitalWrite(pin,val) thread-safe.
I was getting the following exceptions sometimes:
The fix seems to make digitalWrite() a critical section so that no other thread will use it:
Without this, I could only go three or four times through my robot loop before an exception. With this change to PDALib.v93.py, I have gone through the loop over 60 times, before getting an exception....
This time in readDIo().
So the solution looks to be to add the following at the start of PDALib.93.py:
and add the line:
to:
pinMode()
digitalRead()
digitalWrite()
analogRead()
analogWrite()
servoWrite()
I have not had an exception this evening. This was a shotgun approach rather than knowlege, so perhaps I over did it. I was getting tired of typing the: ps -ef | grep python, kill -9 xxxx
I would have to write a test program that launched threads to bang each PDALib public function repeatedly to be sure PDALib is now thread-safe, but not right now.
I was getting the following exceptions sometimes:
File "/home/pi/RWPi/PDALib.py", line 324, in writeDio
r = spi.xfer([0x40,reg,val&255,val>>8])
IOError: [Errno 9] Bad file descriptor
The fix seems to make digitalWrite() a critical section so that no other thread will use it:
- Code: Select all
import threading
dio_lock = threading.Lock()
...
def digitalWrite(pin,val):
with dio_lock: # Critical Section - only one thread # ALAN
if pin < 0:
return -1
if pin < 8:
return pi.write(servopin[pin],val)
if pin < 24:
if val:
return setDioBit(DIO_OLAT,pin-8)
else:
return clearDioBit(DIO_OLAT,pin-8)
return -1
Without this, I could only go three or four times through my robot loop before an exception. With this change to PDALib.v93.py, I have gone through the loop over 60 times, before getting an exception....
This time in readDIo().
PDALib.digitalWrite(Motors.M1DirB,0) #set to off/coast
File "/home/pi/RWPi/PDALib.py", line 193, in digitalWrite
return clearDioBit(DIO_OLAT,pin-8)
File "/home/pi/RWPi/PDALib.py", line 356, in clearDioBit
t = readDio(reg)
File "/home/pi/RWPi/PDALib.py", line 319, in readDio
r = spi.xfer([0x41,reg,0,0])
IOError: [Errno 9] Bad file descriptor
So the solution looks to be to add the following at the start of PDALib.93.py:
- Code: Select all
...
import threading
...
dio_lock = threading.Lock()
and add the line:
- Code: Select all
with dio_lock: # critical section #ALAN
to:
pinMode()
digitalRead()
digitalWrite()
analogRead()
analogWrite()
servoWrite()
I have not had an exception this evening. This was a shotgun approach rather than knowlege, so perhaps I over did it. I was getting tired of typing the: ps -ef | grep python, kill -9 xxxx
I would have to write a test program that launched threads to bang each PDALib public function repeatedly to be sure PDALib is now thread-safe, but not right now.