我是否在两个线程中锁定代码?

时间:2013-02-02 10:48:00

标签: python multithreading python-3.x locking

新的线程编程和使用锁 所以我有2个线程 - 一个从COM端口读取标签 - 另一个控制步进电机

在一个帖子中

        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))                       

(我需要防止更改为stepperb,导致最后一行的除零错误)

在另一个从COM端口读取值的线程

            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]))))

我需要哪些(以及什么类型的锁) - 第一个线程是时间敏感的,因此需要具有优先级

问候

西蒙

3 个答案:

答案 0 :(得分:2)

您将不得不锁定期望stepperb_value不要在系列中更改的任何系列访问。在您的情况下,这将是您发布的整个电机控制块。类似地,您应该锁定COM端口线程中stepperb_value的整个赋值,以确保写入是原子的,并且在第一个线程持有锁时不会发生(并且期望值不会更改)。

答案 1 :(得分:2)

那么,你的关键变量是stepperb_value,所以应该“保护”:

我建议您使用Queue来处理所有同步问题(消费者/生产者模式)。事件和条件也是一个合适的解决方案:

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

答案 2 :(得分:2)

如果你只使用CPython,你还有另一种可能性(暂时)。

由于CPython具有Global Interpreter Lock,因此分配是原子的。因此,在使用它之前,可以将stepperb_value拉入电机控制线程中的局部变量,并使用局部变量而不是全局变量。

请注意,您将在此处使用实施细节。您的代码可能无法安全地运行在其他python实现上,例如Jython或IronPython。即使在CPython上,行为可能会在未来发生变化,但我不认为GIL会在Python 5之前消失。