2017-05-24 64 views
0

如何更改在線程(python)的無限循環中運行的函數的參數? 我新的線程和Python,但是這是我想做的事(簡體),如何更改Python中正在運行的線程中的參數值

class myThread (threading.Thread): 
    def __init__(self, i): 
     threading.Thread.__init__(self) 

    def run(i): 
     self.blink(i) 

    def blink(i): 
     if i!=0: 
      if i==1: 
       speed=0.10 
      elif i==2: 
       speed=0.20 
      elif i==3: 
       speed=0.30  

      while(true): 
       print("speed\n") 

i=3 
blinkThread=myThread(i) 
blinkThread.start() 

while(i!=0): 
i=input("Enter 0 to Exit or 1/2/3 to continue\n") 
if i!=0: 
    blinkThread.run(i) 

現在,很明顯這個代碼給出了關於run()方法的錯誤。我想在無限循環中運行函數blink(),但更改'i'變量。我也無法做到這一點,因爲我有其他部分代碼正在執行並行任務。我能做什麼? 謝謝!

回答

0

除了大量的語法錯誤之外,您正在接近整個過程錯誤 - 將工作從運行委派給另一個方法沒有意義,但即使存在,最後的while也會無限循環(如果它是實際上寫爲while True:)從不檢查速度變化。

此外,不要使用run()方法與您的線程進行接口 - 這是在啓動線程時調用的特殊方法,您應該單獨處理自己的更新。

你還應該花一些時間來學習Python中的OOP,因爲這不是一個班級的學習方式。

這裏有一個例子,你想要做什麼,希望它可以幫助你:

import threading 
import time 


class MyThread (threading.Thread): 

    def __init__(self, speed=0.1): 
     self._speed_cache = 0 
     self.speed = i 
     self.lock = threading.RLock() 
     super(MyThread, self).__init__() 

    def set_speed(self, speed): # you can use a proper setter if you want 
     with self.lock: 
      self.speed = speed 

    def run(self): 
     while True: 
      with self.lock: 
       if self.speed == 0: 
        print("Speed dropped to 0, exiting...") 
        break 
       # just so we don't continually print the speed, print only on change 
       if self.speed != self._speed_cache: 
        print("Current speed: {}".format(self.speed)) 
        self._speed_cache = self.speed 
      time.sleep(0.1) # let it breathe 

try: 
    input = raw_input # add for Python 2.6+ compatibility 
except NameError: 
    pass 

current_speed = 3 # initial speed 

blink_thread = MyThread(current_speed) 
blink_thread.start() 

while current_speed != 0: # main loop until 0 speed is selected 
    time.sleep(0.1) # wait a little for an update 
    current_speed = int(input("Enter 0 to Exit or 1/2/3 to continue\n")) # add validation? 
    blink_thread.set_speed(current_speed) 

另外,不要注意穿線不能並行執行什麼 - 它使用GIL到上下文,但之間切換有絕對不是同時執行兩個線程。互斥(鎖)在這個意義上就是爲了確保操作的原子性,而不是實際的排他性。

如果您需要某些東西來實際並行執行(如果您有多個核心,那就是),您需要改用multiprocessing

+0

謝謝...所以基本上我調用了線程類的另一種方法,而不是run(),並修改了該方法中的類屬性。這個屬性值然後被重寫的run()方法使用。這工作正常。只是一個問題。爲什麼我們使用.lock?我已經使用和不使用鎖的代碼,並且在輸出中找不到任何區別 – ARN

+0

嘗試運行一些可訪問「MyThread.speed」屬性的線程,您將看到原因。作爲一般規則 - 如果有多個線程可能有權訪問某個屬性,則應該使用鎖,並且該屬性應該由其所有者線程控制。這個例子太簡單了,不能顯示問題,但即使在這裏沒有鎖定,如果計時恰到好處,您可以打印出'當前速度:0',儘管線程應該以速度'0'退出的規則在下一個週期退出,如果你沒有時間把速度改回到'1')。 – zwer

0

首先要學習的最好的事情就是永遠不要改變來自不同線程的變量。通過隊列進行通信:

import threading 
import queue 

def drive(speed_queue): 
    speed = 1 
    while True: 
     try: 
      speed = speed_queue.get(timeout=1) 
      if speed == 0: 
       break 
     except queue.Empty: 
      pass 
     print("speed:", speed) 

def main(): 
    speed_queue = queue.Queue() 
    threading.Thread(target=drive, args=(speed_queue,)).start() 
    while True: 
     speed = int(input("Enter 0 to Exit or 1/2/3 to continue: ")) 
     speed_queue.put(speed) 
     if speed == 0: 
      break 

main() 
相關問題