python程序bug帮助

时间:2010-08-15 12:15:36

标签: python multithreading

我很快就会有考试。我一直在查看过去的论文,这个问题一直困扰着我。我似乎无法找到程序中的错误,因为我对这一切都很新。任何人都可以帮助我吗?

以下程序包含错误。确定程序所展示的问题类型,并说明如何修复它。

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

2 个答案:

答案 0 :(得分:4)

你的两个帖子之间有一个race condition。基本上,在将data[0]设置为该值的四倍之前,设置data[1]之间会有一段时间。

如果第二个线程进入并在此期间检查值,则会发生数据不一致。

你可以认为两个线程引用他们自己的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()

现在锁不是唯一的方式来同步线程,但它们适用于这种特殊情况。

答案 1 :(得分: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()