我很快就会有考试。我一直在查看过去的论文,这个问题一直困扰着我。我似乎无法找到程序中的错误,因为我对这一切都很新。任何人都可以帮助我吗?
以下程序包含错误。确定程序所展示的问题类型,并说明如何修复它。
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 :(得分: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()