SimpleSi
SimpleSi

Reputation: 833

Do I lock code in both threads?

new to programming in threads and using locks So I've 2 threads - one reading vlaues from COM port - the other one controlling a stepper motor

in one thread

        if stepperb_value != 0: #if stepperb non-zero
            if stepperb_value > 0: # if positive value
                self.step_fine(10,11,12,13,step_delay) #step forward
            else:
                self.step_fine(13,12,11,10,step_delay) #step backwards
            if abs(stepperb_value) != 100:
                time.sleep(10*step_delay*((100/abs(stepperb_value))-1))                       

(I need to prevent a change to stepperb causing a divide by zero error on last line)

in the other thread thats reading the values from the COM port

            if 'stepperb' in dataraw:
                outputall_pos = dataraw.find('stepperb')
                sensor_value = dataraw[(1+outputall_pos+len('stepperb')):].split()
                print "stepperb" , sensor_value[0]
                if isNumeric(sensor_value[0]):
                    stepperb_value =  int(max(-100,min(100,int(sensor_value[0]))))

Where (and what sort of locks) do I need - the first thread is time sensitive so that needs to have priority

regards

Simon

Upvotes: 0

Views: 119

Answers (3)

Jonas Schäfer
Jonas Schäfer

Reputation: 20718

If you're using only CPython, you have another possibility (for now).

As CPython has the Global Interpreter Lock, assignments are atomic. So you can pull stepperb_value into a local variable in your motor control thread before using it and use the local variable instead of the global one.

Note that you'd be using an implementation detail here. Your code possibly won't run safely on other python implementations such as Jython or IronPython. Even on CPython, the behaviour might change in the future, but I don't see the GIL go away before Python 5 or something.

Upvotes: 2

Guy L
Guy L

Reputation: 2954

Well, your critical variable is stepperb_value so that's what should be "guarded":

I suggest you to use Queue which takes care for all the synchronization issues (consumer/producer pattern). Also events and conditions can be a suitable solution:

http://www.laurentluce.com/posts/python-threads-synchronization-locks-rlocks-semaphores-conditions-events-and-queues/

Upvotes: 2

sheu
sheu

Reputation: 5763

You're going to have to lock around any series of accesses that expects stepperb_value not to change in the series. In your case, that would be the entire motor control block you posted. Similarly, you should lock around the entire assignment to stepperb_value in the COM port thread, to ensure that the write is atomic, and does not happen while the first thread holds the lock (and expects the value not to change).

Upvotes: 2

Related Questions