I’ve got an exam coming up soon. I’ve been looking through the past paper, this question keeps bugging me. I can’t seem to find what the bug in the program could be because I’m quite new to all this. Can anyone help me out?
The following program contains a bug. Determine what kind of problem the program exhibits, and show how it can be fixed.
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()
There’s a race condition between your two threads. Basically, there is a time between setting
data[0]to something before settingdata[1]to four times that value.If the second thread comes in and checks the values during that time, the data inconsistency will occur.
You may think the two threads refer to their own
datainformation but that’s not the case. They are both references to the maindataarray. If you really want them to have their own data arrays, you should change:into:
in both
initfunctions.Otherwise (and this is the more likely case where you want to share the data), you need to ensure your threads are properly synchronised so that the data is always consistent, something like using a mutex:
Now locks aren’t the only way to synchronise threads but they’re fine for this particular case.