1

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.

4
  • What's the problem you have with the loop? It seems to run fine on my computer. Commented Nov 24, 2015 at 2:23
  • The problem is for every 20 random students it should print Class 1 has reached its limit, then the next 20 Class 2 had reach its limit, so on until it puts all 100 in classes Commented Nov 24, 2015 at 2:28
  • It keeps saying there all in class 1 Commented Nov 24, 2015 at 2:29
  • Ah-ha, got it. Writing up an answer now. Commented Nov 24, 2015 at 2:38

2 Answers 2

1

There are several problems with this.

  1. The 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).
  2. Your print statements are a bit messed up. Using 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.
  3. 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.
  4. 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.
  5. Because these threads are running asynchronously, it can and does happen that 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() 
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, so much. It skips class 3 and goes to class 4 so it makes the last class 6
@MichaelSchultz: Yes, that's problem #5. You have (at least) two threads that went into the then part of the if conditional before either of them reset Students.count to 0.
0
    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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.