2013-02-02 27 views
0

新的線程編程和使用鎖 所以我已經2個線程 - 從COM端口一個閱讀vlaues - 另一個控制步進電機我是否在兩個線程中都鎖定了代碼?

在一個線程

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

在哪裏(和什麼樣的鎖),我需要 - 第一個線程是時間敏感,因此需要優先

問候

西蒙

回答

2

如果您只使用CPython的,你有另一種可能性(現在)。

由於CPython有Global Interpreter Lock,賦值是原子的。因此,在使用它之前,您可以將stepperb_value拉到您的電機控制線程的局部變量中,並使用局部變量而不是全局變量。

請注意,您將在此處使用實施細節。您的代碼可能無法在其他python實現(如Jython或IronPython)上安全運行。即使在CPython上,這種行爲在未來可能會發生變化,但是我沒有看到GIL在Python 5之前就已經消失了。

+0

我喜歡這個(因爲我不必學會實現鎖定:))但爲什麼它可能不安全 - 一旦我把全局變量的副本放到本地變量中,當然本地一個不能被其他線程操作改變? – SimpleSi

+1

@SimpleSi:它可能是不安全的,因爲賦值是原子的(將全局值複製到本地是原子的)是CPython的實現細節,而不是語言保證。由你決定,但我不認爲「我不需要學習實現鎖定」是一個好主意 - 好的程序員知道多線程問題並知道如何編寫安全的代碼。 – sheu

+0

我不是一個好的程序員:)好吧,然後我會盡力做到這一點:)我需要記住什麼樣的鎖,我不介意延遲thread2,所以我想thread1有任何優先級可用。 – SimpleSi

2

你」將不得不鎖定任何期望stepperb_value不會在系列中更改的系列訪問。在你的情況下,這將是你發佈的整個電機控制塊。同樣,您應該在COM端口線程中將整個任務鎖定到stepperb_value,以確保寫入是原子的,並且在第一個線程持有鎖定(並且期望值不會更改)時不會發生。

相關問題