2010-08-15 43 views
0

我已經有一個考試即將推出。我一直在瀏覽過去的論文,這個問題一直在困擾着我。我似乎無法找到程序中的錯誤,因爲我對這一切都很陌生。誰能幫我嗎?python程序bug幫助

以下程序包含一個錯誤。確定該計劃展示的是什麼類型的問題,並說明如何解決問題。

import threading 
import time 
import random 
#the list "data" must contain two values. 
#The second must always be equal to the first multiplied by 4 

class GeneratorThread(threading.Thread): 
    #Thread for generating value pairs 
    def __init__(self,data): 
     threading.Thread.__init__(self) 
     self.data=data 
    def run(self): 
     while True: 
      #Pick a new first number 
      num=random.randint(0,100) 
      self.data[0]=num 
      #simulate some processing 
      #to calculate second number 
      time.sleep(1) 
      #Place second value into ata 
      self.data[1]=num*4 
      time.sleep(1) 
class ProcessorThread(threading.Thread): 
    #Thread for processing value pairs 
    def __init__(self,data): 
     threading.Thread.__init__(self) 
     self.data=data 
    def run(self): 
     while True: 
      #Process current data 
      num1=self.data[0] 
      num2=self.data[1] 
      print "Values are %d and %d."%(num1,num2) 
      if num2!=num1*4: 
       print "\tDATA INCONSISTENCY!" 
      time.sleep(2) 
if __name__=="__main__": 
    data=[1,4] 
    t1=GeneratorThread(data) 
    t2=ProcessorThread(data) 
    t1.start() 
    t2.start() 
+0

關於代碼佈局不好意思不怎樣,因此正確 – user416384 2010-08-15 12:16:34

+0

勾畫出以供將來參考做到這一點,你可以手動把四個空格每一行之前,或選擇所有你在將代碼粘貼,然後按工具欄中的'1010'按鈕。 – 2010-08-15 12:17:26

+1

http://en.wikipedia.org/wiki/Race_condition#Computing – 2010-08-15 12:33:46

回答

4

你的兩個線程之間有一個race condition。基本上,在將設置爲該值的四倍之前,有一段時間設置data[0]

如果第二個線程進入並在此期間檢查值,則會發生數據不一致。

你可能認爲這兩個線程是指自己的data信息,但情況並非如此。它們都是對主要data陣列的參考。如果你真的希望他們有他們自己的數據數組,你應該改變:

self.data=data 

到:

self.data=data[:] 

兩個init功能。

否則(這是您要共享的數據更可能的情況下),你需要確保你的線程正確同步,使數據始終是一致的,像使用互斥:

#!/usr/bin/python 

import threading 
import time 
import random 
#the list "data" must contain two values. 
#The second must always be equal to the first multiplied by 4 

class GeneratorThread(threading.Thread): 
    #Thread for generating value pairs 
    def __init__(self,data): 
     threading.Thread.__init__(self) 
     self.datamutex=datamutex   # save reference to the mutex. 
     self.data=data 
    def run(self): 
     while True: 
      #Pick a new first number 
      num=random.randint(0,100) 
      self.datamutex.acquire()  # get the mutex. 
      self.data[0]=num 
      #simulate some processing 
      #to calculate second number 
      time.sleep(1) 
      #Place second value into ata 
      self.data[1]=num*4 
      self.datamutex.release()  # release it to allow other thread 
             # to run now that data is consistent. 
      time.sleep(1) 

 

class ProcessorThread(threading.Thread): 
    #Thread for processing value pairs 
    def __init__(self,data): 
     threading.Thread.__init__(self) 
     self.datamutex=datamutex   # save mutex reference. 
     self.data=data 
    def run(self): 
     while True: 
      #Process current data 
      self.datamutex.acquire()  # lock (can only happen if data consistent). 
      num1=self.data[0] 
      num2=self.data[1] 
      self.datamutex.release()  # release it to allow updates. 

      print "Values are %d and %d."%(num1,num2) 
      if num2!=num1*4: 
       print "\tDATA INCONSISTENCY!" 
      time.sleep(2) 

if __name__=="__main__": 
    datamutex = threading.Lock()   # Create the mutex for both threads. 
    data=[1,4] 
    t1=GeneratorThread(data) 
    t2=ProcessorThread(data) 
    t1.start() 
    t2.start() 

現在鎖是不同步線程唯一的方式,但他們的罰款這種特殊情況下。

0

如果您堅持使用線程安全的方式更新和讀取數據,則不需要顯式鎖定。在這種情況下,使用列表中的切片操作是線程安全的事實。

import threading 
import time 
import random 
#the list "data" must contain two values. 
#The second must always be equal to the first multiplied by 4 

class GeneratorThread(threading.Thread): 
    #Thread for generating value pairs 
    def __init__(self,data): 
     threading.Thread.__init__(self) 
     self.data=data 
    def run(self): 
     while True: 
      #Pick a new first number 
      num=random.randint(0,100) 
      data0=num 
      #simulate some processing 
      #to calculate second number 
      time.sleep(1) 
      #Place second value into ata 
      data1=num*4 
      self.data[0:2]=data0,data1 
      time.sleep(1) 
class ProcessorThread(threading.Thread): 
    #Thread for processing value pairs 
    def __init__(self,data): 
     threading.Thread.__init__(self) 
     self.data=data 
    def run(self): 
     while True: 
      #Process current data 
      num1,num2=self.data[0:2] 
      print "Values are %d and %d."%(num1,num2) 
      if num2!=num1*4: 
       print "\tDATA INCONSISTENCY!" 
      time.sleep(2) 
if __name__=="__main__": 
    data=[1,4] 
    t1=GeneratorThread(data) 
    t2=ProcessorThread(data) 
    t1.start() 
    t2.start()