Is a mutex really necessary in this piece of code?

Gio

The code below shows a class which I use for PyQt threading functionality. In my main program I instantiate and start this thread (i.e. I use PyQt's moveToThread, and countdown is the run method.). While the thread is running I frequently call the reset method. I'm not sure if the mutex I've implemented is actually necessary, I hope somebody can clear this up for me. I've executed a quick test in which I've commented out the mutex, this gave me no problems, even when I comment out the time.sleep(1) and call the reset method while the thread is running without any delay. However I wan't to be 100% secure, hence the reason for my question here.

import time
from PyQt4.QtCore import *
from threading import  Lock

class Countdown(QObject):
    finished = pyqtSignal()

    def __init__(self, countdownInSec=30):
        super(Countdown, self).__init__()
        self.COUNTDOWN_IN_SEC = countdownInSec
        self._countdownInSec = self.COUNTDOWN_IN_SEC
        self._mutex = Lock()

    @pyqtSlot()
    def countdown(self):
        while self._countdownInSec > 0:
            print(self._countdownInSec)
            self._mutex.acquire()
            try:
                self._countdownInSec -= 1
            finally:
                self._mutex.release()
            time.sleep(1)
        self.finished.emit()

    def increment(self, seconds):
        self._mutex.acquire()
        try:
            self._countdownInSec += seconds
        finally:
            self._mutex.release()

    def reset(self):
        self._mutex.acquire()
        try:
            self._countdownInSec = self.COUNTDOWN_IN_SEC
        finally:
            self._mutex.release()

extraction of main (only the part that is relevant for this question)

    fpIntervUpdCountdownReset = pyqtSignal()                                             

    def __init__(self):
        self.initFlightPathIntervUpdater()

    def initFlightPathIntervUpdater(self):             
       self.fpIntervUpdCountdownThr = QThread()                                         
       self.fpIntervUpdCountdown = countdown.Countdown()
       self.fpIntervUpdCountdown.moveToThread(self.fpIntervUpdCountdownThr)      
       self.fpIntervUpdCountdown.finished.connect(self.fpIntervUpdCountdownThr.quit)    
       self.fpIntervUpdCountdown.finished.connect(self.flightPathIntervUpdate)                  
       self.fpIntervUpdCountdownThr.started.connect(self.fpIntervUpdCountdown.countdown)

   def flightPathIntervUpdateReq(self):                                                 
       if self.fpIntervUpdCountdownThr.isRunning():                                     
           self.fpIntervUpdCountdown.reset()                                            
       else:                                                                            
           print 'start'                                                                
           self.fpIntervUpdCountdownThr.start()                                         

   @pyqtSlot()                                                                          
   def flightPathIntervUpdate(self):                                                    
       print "perform flightPathIntervUpdate"
swenzel

I would leave it where it is.
If you're unlucky your reset/increment is performed by one thread in the small time window just after the countdown thread reads the counter and before it writes back the result of its decrement. It would then overwrite the updated value without even seeing it.
That time window is incredibly small so it might be very unlikely to happen, but it is possible.

By the way the preferred way to use locks is:

def increment(self, seconds):
    with self._mutex:
        self._countdownInSec += seconds

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Is a mutex really necessary in this piece of code?

From Java

Is isNaN() really necessary?

From Dev

Are optionals really necessary in Swift?

From Dev

Is a JSON header really necessary?

From Dev

Is an antispyware really necessary?

From Dev

PHP security what is really necessary

From Dev

Is the [1] in Muenchian grouping really necessary?

From Dev

Is PHP password salt really necessary?

From Dev

is the decorator pattern really necessary in this example?

From Dev

Is Vuex really necessary in vue 2?

From Dev

Explicit type conversion really necessary?

From Dev

Hibernate HQL: is JOIN really necessary?

From Dev

Is it really necessary for datetime instruction to be this long?

From Dev

How to know what object or piece of code is continually consuming memory when App is really in idle state in iOS 7 with Xcode 5?

From Dev

Understanding a piece of python code

From Java

What are the parenthesis in this piece of code for?

From Dev

Why is this piece of code not faster?

From Dev

Explain a piece of Haskell code

From Dev

Refactoring this piece of code - Rails

From Dev

What is wrong with this piece of code?

From Dev

Is there a Python function for this piece of code?

From Dev

Is this piece of code technically valid?

From Dev

what is wrong with this piece of code?

From Dev

Is this piece of code correct?

From Dev

Matlab: Understanding a piece of code

From Dev

Explain a piece of Haskell code

From Dev

Explanation for a piece of javascript code

From Dev

What is the "returnto" in this piece of code

From Dev

Is there a Python function for this piece of code?