有一位同学正在准备考试,他在复习历年试题时遇到了一道程序错误修复问题。他无法找出程序的错误所在,因此希望有人能够帮助他。
该程序包含一个错误。需要确定程序的错误类型,并展示如何修复它。
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 data
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、解决方案
该程序存在一个条件竞争问题。基本上,在将 data[0] 设置为某个值之前,然后将 data[1] 设置为该值的四倍之间存在一定时间差。
如果第二个线程在这个时间段内进入并检查值,就会发生数据不一致的情况。
我们可以通过使用锁来同步线程,以确保数据始终一致。
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 data
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()
通过使用锁来同步线程,我们解决了条件竞争问题,确保了两个线程可以正确地处理数据。