Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Preventing tread collisions

Reply
Thread Tools

Preventing tread collisions

 
 
Wanderer
Guest
Posts: n/a
 
      12-12-2012
I have a program that has a main GUI and a camera. In the main GUI, you canmanipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separate thread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self..cameraActive. I check to see if the cameraActive flag is false and set thecameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I also check and set and reset the flag in all the menu commands that access the camera. Like this.

def onProperties(self, event):
""" Display a message window with the camera properties
event -- The camera properties menu event
"""
# Update the temperature
if not self.cameraActive:
self.cameraActive = True
self.camera.getTemperature()
camDict = self.camera.getPropertyDict()
self.cameraActive = False
else:
camDict = {'Error': 'Camera Busy'}
dictMessage(camDict, 'Camera Properties')

This works but my question is, is there a better way using semaphores, locks or something else to prevent collisions between threads?

Thanks
 
Reply With Quote
 
 
 
 
Dave Angel
Guest
Posts: n/a
 
      12-12-2012
On 12/12/2012 03:11 PM, Wanderer wrote:
> I have a program that has a main GUI and a camera. In the main GUI, you can manipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separate thread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self.cameraActive. I check to see if the cameraActive flag is false and set the cameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I also check and set and reset the flag in all the menu commands that access the camera. Like this.
>
> def onProperties(self, event):
> """ Display a message window with the camera properties
> event -- The camera properties menu event
> """
> # Update the temperature
> if not self.cameraActive:
> self.cameraActive = True
> self.camera.getTemperature()
> camDict = self.camera.getPropertyDict()
> self.cameraActive = False
> else:
> camDict = {'Error': 'Camera Busy'}
> dictMessage(camDict, 'Camera Properties')
>
> This works


I don't think so. in between the if and the assignment, another thread
could get in there and also set the flag. Then when either one of them
finishes, it'll clear the flag and the other code is unprotected.

For semaphores between multiple threads, you either have to define only
a single thread at any given moment being permitted to modify it, or you
have to use lower-level primitives, sometimes called test+set operation.

i don't know the "right" way to do this in Python, but this isn't it.
> but my question is, is there a better way using semaphores, locks or something else to prevent collisions between threads?
>
> Thanks



--

DaveA

 
Reply With Quote
 
 
 
 
MRAB
Guest
Posts: n/a
 
      12-12-2012
On 2012-12-12 20:11, Wanderer wrote:
> I have a program that has a main GUI and a camera. In the main GUI, you can manipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separate thread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self.cameraActive. I check to see if the cameraActive flag is false and set the cameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I also check and set and reset the flag in all the menu commands that access the camera. Like this.
>
> def onProperties(self, event):
> """ Display a message window with the camera properties
> event -- The camera properties menu event
> """
> # Update the temperature
> if not self.cameraActive:
> self.cameraActive = True
> self.camera.getTemperature()
> camDict = self.camera.getPropertyDict()
> self.cameraActive = False
> else:
> camDict = {'Error': 'Camera Busy'}
> dictMessage(camDict, 'Camera Properties')
>
> This works but my question is, is there a better way using semaphores, locks or something else to prevent collisions between threads?
>

That suffers from a race condition in that self.cameraActive might be
False when it's checked in the 'if' condition but set to True just
afterwards by the other thread.

You could try a non-blocking semaphore:

def __init__(self):
self.cameraActive = Semaphore()

def onProperties(self, event):
""" Display a message window with the camera properties
event -- The camera properties menu event
"""
# Update the temperature
if self.cameraActive.acquire(False): # Non-blocking
# Successfully acquired the semaphore, so the camera wasn't active
self.camera.getTemperature()
camDict = self.camera.getPropertyDict()
self.cameraActive.release()
else:
camDict = {'Error': 'Camera Busy'}

 
Reply With Quote
 
Ian Kelly
Guest
Posts: n/a
 
      12-12-2012
On Wed, Dec 12, 2012 at 1:53 PM, MRAB <(E-Mail Removed)> wrote:
> You could try a non-blocking semaphore:
>
> def __init__(self):
> self.cameraActive = Semaphore()


Why a Semaphore and not just a plain old Lock?
 
Reply With Quote
 
MRAB
Guest
Posts: n/a
 
      12-12-2012
On 2012-12-12 20:58, Ian Kelly wrote:
> On Wed, Dec 12, 2012 at 1:53 PM, MRAB <(E-Mail Removed)> wrote:
>> You could try a non-blocking semaphore:
>>
>> def __init__(self):
>> self.cameraActive = Semaphore()

>
> Why a Semaphore and not just a plain old Lock?
>

Good point. I probably thought of a semaphore because the OP mentioned
it first.
 
Reply With Quote
 
Alexander Blinne
Guest
Posts: n/a
 
      12-13-2012
Am 12.12.2012 21:29, schrieb Dave Angel:
> On 12/12/2012 03:11 PM, Wanderer wrote:
>> I have a program that has a main GUI and a camera. In the main GUI, you can manipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separate thread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self.cameraActive. I check to see if the cameraActive flag is false and set the cameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I also check and set and reset the flag in all the menu commands that access the camera. Like this.
>>
>> def onProperties(self, event):
>> """ Display a message window with the camera properties
>> event -- The camera properties menu event
>> """
>> # Update the temperature
>> if not self.cameraActive:
>> self.cameraActive = True
>> self.camera.getTemperature()
>> camDict = self.camera.getPropertyDict()
>> self.cameraActive = False
>> else:
>> camDict = {'Error': 'Camera Busy'}
>> dictMessage(camDict, 'Camera Properties')
>>
>> This works

>
> I don't think so. in between the if and the assignment, another thread
> could get in there and also set the flag. Then when either one of them
> finishes, it'll clear the flag and the other code is unprotected.


I have a general question about this kinds of things. I see that the
above is a common use case for some kind of lock which does this
testing/locking atomically. But the question is: if I know for sure that
there is no other thread that might get in the way this solution would
be fine, right?

In one of my applications i have a somewhat different case: i have a
list of objects and call the same method of each object, each in its own
thread (which is created and later joined just for this purpose). The
objects are thus only used by that one thread, the main thread waits for
all threads to be finished before accessing those objects again. Do i
really need some kind of locking for those objects?

Greetings
 
Reply With Quote
 
Andrew Robinson
Guest
Posts: n/a
 
      12-13-2012
>> On 12/12/2012 12:29 PM, Dave Angel wrote:
>>> On 12/12/2012 03:11 PM, Wanderer wrote:
>>>> I have a program that has a main GUI and a camera. In the main GUI,
>>>> you can manipulate the images taken by the camera. You can also use
>>>> the menu to check the camera's settings. Images are taken by the
>>>> camera in a separate thread, so the long exposures don't block the
>>>> GUI. I block conflicts between the camera snapshot thread and the
>>>> main thread by setting a flag called self.cameraActive. I check to
>>>> see if the cameraActive flag is false and set the cameraActive to
>>>> True just before starting the thread. I generate an event on exiting
>>>> the thread which sets the cameraActive flag to False. I also check
>>>> and set and reset the flag in all the menu commands that access the
>>>> camera. Like this.
>>>>
>>>> def onProperties(self, event):
>>>> """ Display a message window with the camera properties
>>>> event -- The camera properties menu event
>>>> """
>>>> # Update the temperature
>>>> if not self.cameraActive:
>>>> self.cameraActive = True
>>>> self.camera.getTemperature()
>>>> camDict = self.camera.getPropertyDict()
>>>> self.cameraActive = False
>>>> else:
>>>> camDict = {'Error': 'Camera Busy'}
>>>> dictMessage(camDict, 'Camera Properties')
>>>>
>>>> This works
>>> I don't think so. in between the if and the assignment, another thread
>>> could get in there and also set the flag. Then when either one of them
>>> finishes, it'll clear the flag and the other code is unprotected.
>>>
>>> For semaphores between multiple threads, you either have to define only
>>> a single thread at any given moment being permitted to modify it, or you
>>> have to use lower-level primitives, sometimes called test+set operation.
>>>
>>> i don't know the "right" way to do this in Python, but this isn't it.
>>>> but my question is, is there a better way using semaphores, locks or
>>>> something else to prevent collisions between threads?
>>>>
>>>> Thanks


if you already have the cameraActive variable reset by an event at
thread termination; it's not necessary to set it false in the menu
command. It's better NOT to do that. Your GUI menu functions need only
test to see if self.cameraActive is false, and then set it to true just
before the launch of the second thread. The second thread, itself,
ought never change the cameraActive variable.

I'm also not sure why you are able to obtain the information from the
camera sequentially (camDict?) when you say you are not blocking the GUI.
I assume self.camera.getTemperature() launches the second thread ? Is it,
somehow, explicitly allowing the continued processing of GUI events that
accessing the camera straight in the GUI would not allow?

If you are talking about the Python semaphore library, I don't think you
need it.

Semaphores are really for use when multiple threads wish to access a
resource where more than one thread can use the resource at a time;
That would mean multiple threads using the camera at once... not a good
idea.

The Lock() object essentially does the same thing, but assumes only 1
thread may use it at a time; hence that would be sufficient (if it
were needed at all!).

A lock is in the "thread" library (Python 2.xx) or the "threading"
library (Python 3.xx). Semaphores aren't part of the thread library in
Python 2.xx... (another reason not to bother with them...)

However, Locking will cause the GUI thread to block when the camera is
in use, which isn't what you want -- correct?

There is a way to test the lock but not block, which is equivalent to
your variable (to be honest!); I'm pretty sure that Python doesn't use
true Posix threads but only the GNU Pth library. That means that the
only time threads truly switch is determined by the Python interpreter.
In that case, all python variable assignments are going to be effectively
atomic anyhow... and a variable, like you are using, is identical to a lock.
(Atomic merely means the write can't be interrupted by a thread switch partway
through).

If you have a multi-processing environment, there is a multiprocessor
library -- where the lock or semaphore mechanism would be important.
But I really don't think you need it.



 
Reply With Quote
 
Ian Kelly
Guest
Posts: n/a
 
      12-13-2012
On Thu, Dec 13, 2012 at 3:26 AM, Alexander Blinne <(E-Mail Removed)> wrote:
> I have a general question about this kinds of things. I see that the
> above is a common use case for some kind of lock which does this
> testing/locking atomically. But the question is: if I know for sure that
> there is no other thread that might get in the way this solution would
> be fine, right?


If you know for sure that there is no other thread, then there is no
need for the flag in the first place.

> In one of my applications i have a somewhat different case: i have a
> list of objects and call the same method of each object, each in its own
> thread (which is created and later joined just for this purpose). The
> objects are thus only used by that one thread, the main thread waits for
> all threads to be finished before accessing those objects again. Do i
> really need some kind of locking for those objects?


No, if a resource is only ever used by one thread/process, then there
is no reason to lock it.
 
Reply With Quote
 
Wanderer
Guest
Posts: n/a
 
      12-13-2012
On Wednesday, December 12, 2012 3:53:28 PM UTC-5, MRAB wrote:
> On 2012-12-12 20:11, Wanderer wrote:
>
> > I have a program that has a main GUI and a camera. In the main GUI, youcan manipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separatethread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self.cameraActive. I check to see if the cameraActive flag is false and setthe cameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I alsocheck and set and reset the flag in all the menu commands that access the camera. Like this.

>
> >

>
> > def onProperties(self, event):

>
> > """ Display a message window with the camera properties

>
> > event -- The camera properties menu event

>
> > """

>
> > # Update the temperature

>
> > if not self.cameraActive:

>
> > self.cameraActive = True

>
> > self.camera.getTemperature()

>
> > camDict = self.camera.getPropertyDict()

>
> > self.cameraActive = False

>
> > else:

>
> > camDict = {'Error': 'Camera Busy'}

>
> > dictMessage(camDict, 'Camera Properties')

>
> >

>
> > This works but my question is, is there a better way using semaphores, locks or something else to prevent collisions between threads?

>
> >

>
> That suffers from a race condition in that self.cameraActive might be
>
> False when it's checked in the 'if' condition but set to True just
>
> afterwards by the other thread.
>
>
>
> You could try a non-blocking semaphore:
>
>
>
> def __init__(self):
>
> self.cameraActive = Semaphore()
>
>
>
> def onProperties(self, event):
>
> """ Display a message window with the camera properties
>
> event -- The camera properties menu event
>
> """
>
> # Update the temperature
>
> if self.cameraActive.acquire(False): # Non-blocking
>
> # Successfully acquired the semaphore, so the camera wasn't active
>
> self.camera.getTemperature()
>
> camDict = self.camera.getPropertyDict()
>
> self.cameraActive.release()
>
> else:
>
> camDict = {'Error': 'Camera Busy'}


Thanks. Why Non-blocking?
 
Reply With Quote
 
Wanderer
Guest
Posts: n/a
 
      12-13-2012
On Wednesday, December 12, 2012 3:53:28 PM UTC-5, MRAB wrote:
> On 2012-12-12 20:11, Wanderer wrote:
>
> > I have a program that has a main GUI and a camera. In the main GUI, youcan manipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separatethread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self.cameraActive. I check to see if the cameraActive flag is false and setthe cameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I alsocheck and set and reset the flag in all the menu commands that access the camera. Like this.

>
> >

>
> > def onProperties(self, event):

>
> > """ Display a message window with the camera properties

>
> > event -- The camera properties menu event

>
> > """

>
> > # Update the temperature

>
> > if not self.cameraActive:

>
> > self.cameraActive = True

>
> > self.camera.getTemperature()

>
> > camDict = self.camera.getPropertyDict()

>
> > self.cameraActive = False

>
> > else:

>
> > camDict = {'Error': 'Camera Busy'}

>
> > dictMessage(camDict, 'Camera Properties')

>
> >

>
> > This works but my question is, is there a better way using semaphores, locks or something else to prevent collisions between threads?

>
> >

>
> That suffers from a race condition in that self.cameraActive might be
>
> False when it's checked in the 'if' condition but set to True just
>
> afterwards by the other thread.
>
>
>
> You could try a non-blocking semaphore:
>
>
>
> def __init__(self):
>
> self.cameraActive = Semaphore()
>
>
>
> def onProperties(self, event):
>
> """ Display a message window with the camera properties
>
> event -- The camera properties menu event
>
> """
>
> # Update the temperature
>
> if self.cameraActive.acquire(False): # Non-blocking
>
> # Successfully acquired the semaphore, so the camera wasn't active
>
> self.camera.getTemperature()
>
> camDict = self.camera.getPropertyDict()
>
> self.cameraActive.release()
>
> else:
>
> camDict = {'Error': 'Camera Busy'}


Thanks. Why Non-blocking?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Tread Local Performance Metrics. addicted.adi Java 0 01-17-2011 08:55 AM
the file or directory is corrupted and unreadable. Windows 2000 Can'tread it but 2003 can. Crypto Computer Support 0 12-31-2007 08:36 AM
ARP Request Collisions on PIX-501 firewall Andrew Dancy Cisco 2 06-13-2007 11:47 AM
Collisions with Full-Duplex Jim Cisco 9 01-05-2004 02:41 PM
Cisco MC3810 with multiple ethernet collisions JFerri Cisco 1 11-19-2003 01:12 AM



Advertisments