Threads/.DS_Store

Threads/.DS_Store

“”” File: bank.py This module defines the Bank class. “”” import pickle import random from savingsaccount import SavingsAccount class Bank: “””This class represents a bank as a collection of savings accounts. An optional file name is also associated with the bank, to allow transfer of accounts to and from permanent file storage.””” # The state of the bank is a dictionary of accounts and # a file name. If the file name is None, a file name # for the bank has not yet been established. def __init__(self, fileName = None): “””Creates a new dictionary to hold the accounts. If a file name is provided, loads the accounts from a file of pickled accounts.””” self.accounts = {} self.fileName = fileName if fileName != None: fileObj = open(fileName, ‘rb’) while True: try: account = pickle.load(fileObj) self.add(account) except Exception: fileObj.close() break def __str__(self): “””Returns the string representation of the bank.””” return “\n”.join(map(str, self.accounts.values())) def makeKey(self, name, pin): “””Returns a key for the account.””” return name + “/” + pin def add(self, account): “””Adds the account to the bank.””” key = self.makeKey(account.getName(), account.getPin()) self.accounts[key] = account def remove(self, name, pin): “””Removes the account from the bank and and returns it, or None if the account does not exist.””” key = self.makeKey(name, pin) return self.accounts.pop(key, None) def get(self, name, pin): “””Returns the account from the bank, or returns None if the account does not exist.””” key = self.makeKey(name, pin) return self.accounts.get(key, None) def computeInterest(self): “””Computes and returns the interest on all accounts.””” total = 0 for account in self._accounts.values(): total += account.computeInterest() return total def getKeys(self): “””Returns a sorted list of keys.””” # Exercise return [] def save(self, fileName = None): “””Saves pickled accounts to a file. The parameter allows the user to change file names.””” if fileName != None: self.fileName = fileName elif self.fileName == None: return fileObj = open(self.fileName, ‘wb’) for account in self.accounts.values(): pickle.dump(account, fileObj) fileObj.close() # Functions for testing def createBank(numAccounts = 1): “””Returns a new bank with the given number of accounts.””” names = (“Brandon”, “Molly”, “Elena”, “Mark”, “Tricia”, “Ken”, “Jill”, “Jack”) bank = Bank() upperPin = numAccounts + 1000 for pinNumber in range(1000, upperPin): name = random.choice(names) balance = float(random.randint(100, 1000)) bank.add(SavingsAccount(name, str(pinNumber), balance)) return bank def testAccount(): “””Test function for savings account.””” account = SavingsAccount(“Ken”, “1000”, 500.00) print(account) print(account.deposit(100)) print(“Expect 600:”, account.getBalance()) print(account.deposit(-50)) print(“Expect 600:”, account.getBalance()) print(account.withdraw(100)) print(“Expect 500:”, account.getBalance()) print(account.withdraw(-50)) print(“Expect 500:”, account.getBalance()) print(account.withdraw(100000)) print(“Expect 500:”, account.getBalance()) def main(number = 10, fileName = None): “””Creates and prints a bank, either from the optional file name argument or from the optional number.””” testAccount() ## if fileName: ## bank = Bank(fileName) ## else: ## bank = createBank(number) ## print(bank) if __name__ == “__main__”: main()

Threads/counter.py

“”” File: counter.py “”” class Counter(object): “””Models a counter.””” # Constructor def __init__(self): “””Sets up the counter.””” self.reset() # Mutator methods def reset(self): “””Returns the counter to 0.””” self.value = 0 def increment(self, amount = 1): “””Adds amount to the counter.””” self.value += amount return self.value def decrement(self, amount = 1): “””Subtracts amount from the counter.””” self.value -= amount # Accessor methods def getValue(self): “””Returns the counter’s value.””” return self.value def __str__(self): “””Returns the string representation of the counter.””” return str(self.value) def __eq__(self, other): “””Returns True if self equals other or False otherwise.””” if self is other: return True if type(self) != type(other): return False return self.value == other._value

Threads/producerconsumer1.py

“”” File: producerconsumer1.py Producer-consumer demo with no synchronization. Producer and consumer both access shared data a given number of times. They sleep a random interval before each access. The data must be produced before it is consumed, and be produced and consumed just once. However, on some runs, the producer and consumer may access the data out of order. “”” import time, random from threading import Thread, currentThread class SharedCell(object): “””Shared data for the producer/consumer problem.””” def __init__(self): “””Data undefined at startup.””” self.data = -1 def setData(self, data): “””Producer’s method to write to shared data.””” print(“%s setting data to %d” % \ (currentThread().getName(), data)) self.data = data def getData(self): “””Consumer’s method to read from shared data.””” print(“%s accessing data %d” % \ (currentThread().getName(), self.data)) return self.data class Producer(Thread): “””A producer of data in a shared cell.””” def __init__(self, cell, accessCount, sleepMax): “””Create a producer with the given shared cell, number of accesses, and maximum sleep interval.””” Thread.__init__(self, name = “Producer”) self.accessCount = accessCount self.cell = cell self.sleepMax = sleepMax def run(self): “””Resets the data in the cell and goes to sleep, the given number of times.””” print(“%s starting up” % self.getName()) for count in range(self.accessCount): time.sleep(random.randint(1, self.sleepMax)) self.cell.setData(count + 1) print(“%s is done producing\n” % self.getName()) class Consumer(Thread): “””A consumer of data in a shared cell.””” def __init__(self, cell, accessCount, sleepMax): “””Create a consumer with the given shared cell, number of accesses, and maximum sleep interval.””” Thread.__init__(self, name = “Consumer”) self.accessCount = accessCount self.cell = cell self.sleepMax = sleepMax def run(self): “””Announce start-up, sleep and write to shared cell the given number of times, and announce completion.””” print(“%s starting up\n” % self.getName()) for count in range(self.accessCount): time.sleep(random.randint(1, self.sleepMax)) value = self.cell.getData() print(“%s is done consuming\n” % self.getName()) def main(): accessCount = int(input(“Enter the number of accesses: “)) sleepMax = 4 cell = SharedCell() p = Producer(cell, accessCount, sleepMax) c = Consumer(cell, accessCount, sleepMax) print(“Starting the threads”) p.start() c.start() main()

Threads/producerconsumer2.py

“”” File: producerconsumer2.py Producer-consumer demo with synchronization. Producer and consumer both access shared data a given number of times. They sleep a random interval before each access. The data must be produced before it is consumed, and be produced and consumed just once. The condition and Boolean flag on the shared data guarantee that the producer and consumer access the data in the correct order. “”” import time, random from threading import Thread, currentThread, Condition class SharedCell(object): “””Shared data that sequences writing before reading.””” def __init__(self): “””Can produce but not consume at startup.””” self.data = -1 self.writeable = True self.condition = Condition() def setData(self, data): “””Second caller must wait until someone has consumed the data before resetting it.””” self.condition.acquire() while not self.writeable: self.condition.wait() print(“%s setting data to %d” % \ (currentThread().getName(), data)) self.data = data self.writeable = False self.condition.notify() self.condition.release() def getData(self): “””Caller must wait until someone has produced the data before accessing it.””” self.condition.acquire() while self.writeable: self.condition.wait() print(“%s accessing data %d” % \ (currentThread().getName(), self.data)) self.writeable = True self.condition.notify() self.condition.release() return self.data class Producer(Thread): “””A producer of data in a shared cell.””” def __init__(self, cell, accessCount, sleepInterval): Thread.__init__(self, name = “Producer”) self.accessCount = accessCount self.cell = cell self.sleepInterval = sleepInterval def run(self): “””Resets the data in the cell and goes to sleep, the given number of times.””” print(“%s starting up” % self.getName()) for count in range(self.accessCount): time.sleep(random.randint(1, self.sleepInterval)) self.cell.setData(count + 1) print(“%s is done producing\n” % self.getName()) class Consumer(Thread): “””A consumer of data in a shared cell.””” def __init__(self, cell, accessCount, sleepInterval): Thread.__init__(self, name = “Consumer”) self.accessCount = accessCount self.cell = cell self.sleepInterval = sleepInterval def run(self): “””Accesses the data in the cell and goes to sleep, the given number of times.””” print(“%s starting up\n” % self.getName()) for count in range(self.accessCount): time.sleep(random.randint(1, self.sleepInterval)) value = self.cell.getData() print(“%s is done consuming\n” % self.getName()) def main(): accessCount = int(input(“Enter the number of accesses: “)) cell = SharedCell() p = Producer(cell, accessCount, 4) c = Consumer(cell, accessCount, 4) print(“Starting the threads”) p.start() c.start() if __name__ == “__main__”: main()

Threads/readersandwriters.py

“”” File: readersandwriters.py Demonstrates shared data synchonization for the readers and writers problem. To be completed in the programing projects. “”” import time, random from threading import Thread from sharedcell import SharedCell from counter import Counter class Writer(Thread): “””Increments a counter in a shared cell.””” def __init__(self, cell, number): Thread.__init__(self, name = “Writer” + str(number)) self.cell = cell def run(self): “””Sleep for a random interval and then increment the counter in the cell.””” print(“%s starting up” % self.getName()) time.sleep(random.randint(1, 4)) # write, using counter’s increment # value = ? print(“%s is done incrementing to %d” % \ (self.getName(), value)) class Reader(Thread): “””Reads the value of a counter in a shared cell.””” def __init__(self, cell, number): Thread.__init__(self, name = “Reader” + str(number)) self.cell = cell def run(self): “””Sleep for a random interval and then get the value of the counter in the cell.””” print(“%s starting up” % self.getName()) time.sleep(random.randint(1, 4)) # read, using counter’s getValue # value = ? print(“%s is done getting %d” % (self.getName(), value)) def main(): “””Creates a shared cell on a Counter object, and reader and writer threads to increment it and observe its value.””” counter = Counter() cell = SharedCell(counter) threads = [] print(“Creating reader threads.”) for i in range(1, 5): threads.append(Reader(cell, i)) print(“Creating writer threads.”) for i in range(1, 3): threads.append(Writer(cell, i)) print(“Starting the threads.”) for thread in threads: thread.start() if __name__ == “__main__”: main()

Threads/savingsaccount.py

“”” File: savingsaccount.py This module defines the SavingsAccount class. “”” class SavingsAccount: “””This class represents a savings account with the owner’s name, PIN, and balance.””” RATE = 0.02 def __init__(self, name, pin, balance = 0.0): self.name = name self.pin = pin self.balance = balance def __str__(self): result = ‘Name: ‘ + self.name + ‘\n’ result += ‘PIN: ‘ + self.pin + ‘\n’ result += ‘Balance: ‘ + str(self.balance) return result def getBalance(self): “””Returns the current balance.””” return self.balance def getName(self): “””Returns the current name.””” return self.name def getPin(self): “””Returns the current pin.””” return self.pin def deposit(self, amount): “””If the amount is valid, adds it to the balance and returns None; otherwise, returns an error message.””” self.balance += amount return None def withdraw(self, amount): “””If the amount is valid, sunstract it from the balance and returns None; otherwise, returns an error message.””” if amount < 0: return “Amount must be >= 0” elif self.balance < amount: return “Insufficient funds” else: self.balance -= amount return None def computeInterest(self): “””Computes, deposits, and returns the interest.””” interest = self.balance * SavingsAccount.RATE self.deposit(interest) return interest

Threads/sharedcell.py

“”” File: sharedcell.py Resource for shared data synchonization for the readers and writers problem. Guarantees that a writer finishes writing before readers can read and other writers can write. Also supports concurrent reading. “”” from threading import Condition class SharedCell(object): “””Synchronizes readers and writers around shared data, to support thread-safe reading and writing.””” def __init__(self, data): “””Sets up the conditions and count of active readers.””” self.data = data self.writing = False self.readerCount = 0 self.okToRead = Condition() self.okToWrite = Condition() def beginRead(self): “””Waits until a writer is not writing or the writers condition queue is empty. Then increments the reader count and notifies the next waiting reader.””” self.okToRead.acquire() self.okToWrite.acquire() while self.writing or len(self.okToWrite._waiters) > 0: self.okToRead.wait() self.readerCount += 1 self.okToRead.notify() def endRead(self): “””Notifies a waiting writer if there are no active readers.””” self.readerCount -= 1 if self.readerCount == 0: self.okToWrite.notify() self.okToWrite.release() self.okToRead.release() def beginWrite(self): “””Can write only when someone else is not writing and there are no readers are ready.””” self.okToWrite.acquire() self.okToRead.acquire() while self.writing or self.readerCount != 0: self.okToWrite.wait() self.writing = True def endWrite(self): “””Notify the next waiting writer if the readers condition queue is empty. Otherwise, notify the next waiting reader.””” self.writing = False if len(self.okToRead._waiters) > 0: self.okToRead.notify() else: self.okToWrite.notify() self.okToRead.release() self.okToWrite.release() def read(self, readerFunction): “””Observe the data in the shared cell.””” self.beginRead() # Enter reader’s critical section result = readerFunction(self.data) # Exit reader’s critical section self.endRead() return result def write(self, writerFunction): “””Modify the data in the shared cell.””” self.beginWrite() # Enter writer’s critical section result = writerFunction(self.data) # Exit writer’s critical section self.endWrite() return result

Threads/sleepythreads.py

“”” File: sleepythreads.py Illustrates concurrency with multiple threads. “”” import random, time from threading import Thread class SleepyThread(Thread): “””Represents a sleepy thread.””” def __init__(self, number, sleepMax): “””Create a thread with the given name and a random sleep interval less than the maximum. “”” Thread.__init__(self, name = “Thread ” + str(number)) self.sleepInterval = random.randint(1, sleepMax) def run(self): “””Print the thread’s name and sleep interval and sleep for that interval. Print the name again at wakeup. “”” print(“%s starting, with sleep interval: %d seconds” % \ (self.getName(), self.sleepInterval)) time.sleep(self.sleepInterval) print(“%s waking up” % self.getName()) def main(): “””Create the user’s number of threads with sleep intervals less than the user’s maximum. Then start the threads””” numThreads = int(input(“Enter the number of threads: “)) sleepMax = int(input(“Enter the maximum sleep time: “)) threadList = [] for count in range(numThreads): threadList.append(SleepyThread(count + 1, sleepMax)) for thread in threadList: thread.start() if __name__ == “__main__”: main()

Threads/threadexample1.py

“”” File: threadexample1.py First demo of a thread. “”” from threading import Thread class MyThread(Thread): “””A thread that prints its name.””” def __init__(self, name): Thread.__init__(self, name = name) def run(self): print(“Hello, my name is %s” % self.getName()) def main(): “””Create the thread and start it.””” thread = MyThread(“Ken”) thread.start() if __name__ == “__main__”: main()

Threads/threadsafesavingsaccount.py

“”” File: threadsafesavingsaccount.py This module defines a thread-safe SavingsAccount class. “”” from savingsaccount import SavingsAccount from sharedcell import SharedCell class ThreadSafeSavingsAccount: “””This class represents a thread-safe savings account with the owner’s name, PIN, and balance.””” def __init__(self, name, pin, balance = 0.0): “””Wrap a new account in a shared cell for thread-safety.””” account = SavingsAccount(name, pin, balance) self.cell = SharedCell(account) def __str__(self): “””Returns the string rep of the account.””” return self.cell.read(lambda account: str(account)) def getBalance(self): “””Returns the current balance.””” return self.cell.read(lambda account: account.getBalance()) def getName(self): “””Returns the current name.””” return self.cell.read(lambda account: account.getName()) def getPin(self): “””Returns the current pin.””” return self.cell.read(lambda account: account.getPin()) def deposit(self, amount): “””If the amount is valid, adds it to the balance and returns None; otherwise, returns an error message.””” return self.cell.write(lambda account: account.deposit(amount)) # Other methods are exercises


Comments are closed.