Reputation: 109
I am have problem with this THREDING example. I have it working pretty good, but my problem is after it shows all 100 student threads. I am trying to put 20 random students in five different classes, but no matter what I do I can't seem to get the loop to work. If someone could please give me any direction on this, I would greatly appreciate it.
import random, time
from threading import Thread
class Students(Thread):
''' Represents a sleepy thread.'''
def __init__(self, number, sleepMax):
''' Creates a thread with a given Name
and a random sleep interval less than the maximum. '''
Thread.__init__(self, name = "Student " + str(number))
self._RequestInterval = random.randint(1, sleepMax)
def run(self):
'''Prints the thread's name and sleep interval and sleep
for that interval. Print the name again at wake-up. '''
count = 1
course = 1
print(" %s, Awaiting Request: %d seconds" % \
( self.getName(), self._RequestInterval))
time.sleep(self._RequestInterval)
if count == 20:
print("%s Has A Spot Obtained in Class" % self.getName(), + course)
print("Class", course, "has reached it limit!")
count += 1
course =+ 1
else:
#print("Class ", course, " is full.")
print("%s Has A Spot Obtained in Class" % self.getName(), + course)
def main():
''' Creates the user's number of threads with sleep
interval less than the user's maximum. Then start
the threads'''
NumberOfStudents = 100
RequestTimer = 5
threadList = []
for count2 in range(NumberOfStudents):
threadList.append(Students(count2 + 1, RequestTimer))
for thread in threadList: thread.start()
main()
I have even tried running my variable outside the class, but crashes.
Upvotes: 1
Views: 262
Reputation: 53
def run(self):
'''Prints the thread's name and sleep interval and sleep
for that interval. Print the name again at wake-up. '''
count = 1
course = 1
The variable count
and course
are both under the class instance, like you can think of there are 100 count
variables and same to course
If you tried move the two outside the class, you should add a gloabl
reference, like:
def run(self):
'''Prints the thread's name and sleep interval and sleep
for that interval. Print the name again at wake-up. '''
global count, course
count = 1
course = 1
this could be prevent crash, but not the result too. you can think of that there is only one count
and course
, but you have 100 threads running same time, maybe they are all use count=1
, or some count=1
some count=2
...
So, we need to add the Mutex
to the public variable (which we think its a resource, need to set mutex for threading safe).
The code:
import random, time, threading
count = 1
course = 1
mutex = threading.Lock()
class Students(threading.Thread):
''' Represents a sleepy thread.'''
def __init__(self, number, sleepMax):
''' Creates a thread with a given Name
and a random sleep interval less than the maximum. '''
threading.Thread.__init__(self, name = "Student " + str(number))
self._RequestInterval = random.randint(1, sleepMax)
def run(self):
'''Prints the thread's name and sleep interval and sleep
for that interval. Print the name again at wake-up. '''
global count, course
print(" %s, Awaiting Request: %d seconds" % ( self.getName(), self._RequestInterval))
time.sleep(self._RequestInterval)
if mutex.acquire(1):
print("%s Has A Spot Obtained in Class" % self.getName(), + course)
if count == 20:
count = 1
course += 1
else:
count += 1
mutex.release()
def main():
''' Creates the user's number of threads with sleep
interval less than the user's maximum. Then start
the threads'''
NumberOfStudents = 100
RequestTimer = 5
threadList = []
for count2 in range(NumberOfStudents):
threadList.append(Students(count2 + 1, RequestTimer))
for thread in threadList: thread.start()
main()
Upvotes: 0
Reputation: 2244
There are several problems with this.
count
and course
variables are only in the run
function, so they are local to that function only. This means that threads are not sharing this information. The solution: move them outside so that they are class variables (that is, they are now Students.count
and Students.course
).print(a,b,c,...)
will print each of a,b,c,...
on a separate line. The solution, enclose the thread's name and course number in a tuple and modify the format string slightly.course =+ 1
would've set course
to 1
(because it's the same thing as course = +1
) had that part of the if statement ever been executed (which it wasn't because of problem #1). Solution: flip the =+
so that it's course += 1
.count += 1
only happens when count
is 20. You want this in the else part of the if statement. Also, in the then part, add the the line count = 0
to reset the count.count
will go from 19 to 21 before you check if count == 20
. Fixing this requires somewhat more advanced thread handling.Below is the code with each of these problems fixed, except the last one (where I changed count == 20
to count >= 20
to at least show something interesting happen).
import random, time
from threading import Thread
class Students(Thread):
''' Represents a sleepy thread.'''
count = 1
course = 1
def __init__(self, number, sleepMax):
''' Creates a thread with a given Name
and a random sleep interval less than the maximum. '''
Thread.__init__(self, name = "Student " + str(number))
self._RequestInterval = random.randint(1, sleepMax)
def run(self):
'''Prints the thread's name and sleep interval and sleep
for that interval. Print the name again at wake-up. '''
print(" %s, Awaiting Request: %d seconds" % \
( self.getName(), self._RequestInterval))
time.sleep(self._RequestInterval)
if Students.count >= 20:
print("%s Has A Spot Obtained in Class %s" % (self.getName(), Students.course))
print("Class", Students.course, "has reached it limit!")
Students.course += 1
Students.count = 0
else:
#print("Class ", course, " is full.")
print("%s Has A Spot Obtained in Class %s" % (self.getName(), Students.course))
Students.count += 1
def main():
''' Creates the user's number of threads with sleep
interval less than the user's maximum. Then start
the threads'''
NumberOfStudents = 100
RequestTimer = 5
threadList = []
for count2 in range(NumberOfStudents):
threadList.append(Students(count2 + 1, RequestTimer))
for thread in threadList: thread.start()
main()
Upvotes: 1