├── FibonacciThread.py ├── OS.pdf ├── OS.png ├── ProducerConsumer.py ├── README.md ├── cpuBoundProcesses1.py ├── cpuBoundThread1.py ├── fib1.py ├── fibonacciThreadServer.py ├── fork1.py ├── grabURLsThreads.py ├── ioBoundProcesses1.py ├── ioBoundThread1.py ├── mappool1.py ├── multiprocess2.py ├── multiprocessing1.py ├── queue1.py ├── subprocess1.py ├── threadChat.py ├── threadFib.py ├── threading1.py ├── threading1a.py ├── threading2.py ├── threading3.py ├── threading4.py ├── threading5.py └── threads4.py /FibonacciThread.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #calculate fibonacci using Threads 3 | from socket import * 4 | from threading import Thread 5 | import datetime 6 | 7 | # Fibonacci Network Server 8 | def fib_server(address): 9 | sock = socket(AF_INET, SOCK_STREAM) 10 | sock.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 11 | sock.bind(address) 12 | sock.listen(5) 13 | while True: 14 | client, addr = sock.accept() 15 | print("[+] Connection started with: ", addr) 16 | Thread(target=fib_handler_yield, args=(client,), daemon=True).start() 17 | 18 | #Calculating fibonacci 19 | def fibonacci_yield(n): 20 | l1=1; yield 1 21 | l2=1; yield 1 22 | for i in range(2,n): 23 | l=l1+l2; 24 | yield l 25 | l1, l2 = l2, l 26 | 27 | #Network fibonacci client handler 28 | def fib_handler_yield(client): 29 | while True: 30 | req = client.recv(100) 31 | if not req: 32 | break 33 | n = int(req) 34 | a = datetime.datetime.now() 35 | results=list(fibonacci_yield(n)) 36 | #results = itertools.islice(l, n) 37 | b = datetime.datetime.now() 38 | diff = b - a 39 | print ("the calc took: %d days" % diff.days) 40 | print ("the calc took: %d seconds" % diff.seconds) 41 | print ("the calc took: %d microseconds" % diff.microseconds) 42 | 43 | resp = str(results[n-1]).encode('ascii') + str(diff.microseconds).encode('ascii') + b'\n' 44 | client.send(resp) 45 | print("[+] Connection Closed !!!") 46 | 47 | fib_server(('',25001)) 48 | 49 | #Testing yield 50 | #x = fibonacci_yield(n) 51 | #print(x.__next__()) 52 | -------------------------------------------------------------------------------- /OS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashemery/OS/58a27b0584a2f4594adc52cec76dbf16edbaff22/OS.pdf -------------------------------------------------------------------------------- /OS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashemery/OS/58a27b0584a2f4594adc52cec76dbf16edbaff22/OS.png -------------------------------------------------------------------------------- /ProducerConsumer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Standard Producer/Consumer Threading Pattern 3 | ''' 4 | 5 | import time 6 | import threading 7 | #import Queue 8 | from multiprocessing import Queue 9 | 10 | class Consumer(threading.Thread): 11 | def __init__(self, queue): 12 | threading.Thread.__init__(self) 13 | self._queue = queue 14 | 15 | def run(self): 16 | while True: 17 | # queue.get() blocks the current thread until 18 | # an item is retrieved. 19 | msg = self._queue.get() 20 | # Checks if the current message is 21 | # the "Poison Pill" 22 | if isinstance(msg, str) and msg == 'quit': 23 | # if so, exists the loop 24 | break 25 | # "Processes" (or in our case, prints) the queue item 26 | print ("I'm a thread, and I received %s!!" % msg) 27 | # Always be friendly! 28 | print ('Bye byes!') 29 | 30 | 31 | def Producer(): 32 | # Queue is used to share items between 33 | # the threads. 34 | queue = Queue.Queue() 35 | 36 | # Create an instance of the worker 37 | worker = Consumer(queue) 38 | # start calls the internal run() method to 39 | # kick off the thread 40 | worker.start() 41 | 42 | # variable to keep track of when we started 43 | start_time = time.time() 44 | # While under 5 seconds.. 45 | while time.time() - start_time < 5: 46 | # "Produce" a piece of work and stick it in 47 | # the queue for the Consumer to process 48 | queue.put('something at %s' % time.time()) 49 | # Sleep a bit just to avoid an absurd number of messages 50 | time.sleep(1) 51 | 52 | # This the "poison pill" method of killing a thread. 53 | queue.put('quit') 54 | # wait for the thread to close down 55 | worker.join() 56 | 57 | 58 | if __name__ == '__main__': 59 | Producer() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Operating Systems 2 | Everything that I used to learn Operating Systems. It also includes the Python code that I used to use for illustrating different operating system terminologies, techniques, and solutions. 3 | 4 | ### Good OS Learning Resources 5 | The list below is based on my readings and personal opinions only. 6 | 7 | ## Courses 8 | - Introduction to Operating Systems, by Georgia Tech. [URL](https://www.udacity.com/course/introduction-to-operating-systems--ud923) 9 | - Advanced Operating Systems, by Georgia Tech. [URL](https://www.udacity.com/course/advanced-operating-systems--ud189) 10 | - Computer System Engineering, Undergraduate / MIT. [URL](https://ocw.mit.edu/courses/6-033-computer-system-engineering-spring-2018/) 11 | - Operating System Engineering, Graduate / MIT. [URL](https://ocw.mit.edu/courses/6-828-operating-system-engineering-fall-2012/) 12 | - Operating Systems and System Programming, by UC Berkeley Computer Science. [URL](https://www.youtube.com/playlist?list=PLggtecHMfYHA7j2rF7nZFgnepu_uPuYws) 13 | - OPS Class, by Geoffrey Challen. [URL1](https://ops-class.org/) and [URL2](https://www.youtube.com/playlist?list=PLE6LEE8y2Jp_z8pkiuvHo7Vz-eQEKsk-I) 14 | - Operating Systems for Ghassan Shobaki Computer Science Lectures. [URL](https://www.youtube.com/playlist?list=PL6KMWPQP_DM-7tMNjUa7X2zGrc8jipPeI) 15 | -- A previous colleague of mine and that's why I added this course and because I know he is an amazing professor! 16 | 17 | --- 18 | 19 | ## Books 20 | - Operating System Concepts, by Abraham Silberschatz, Greg Gagne, and Peter Galvin. [URL](https://www.amazon.com/Operating-System-Concepts-Abraham-Silberschatz/dp/1119800366/) 21 | - Modern Operating Systems, by Andrew Tanenbaum and Herbert Bos. [URL](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X/) 22 | - The Linux Programming Interface: A Linux and UNIX System Programming Handbook, by Michael Kerrisk. [URL](https://www.amazon.com/Linux-Programming-Interface-System-Handbook/dp/1593272200/) 23 | - Windows 10 System Programming - Part 1, by Pavel Yosifovich. [URL](https://www.amazon.com/Windows-10-System-Programming-Part/dp/B086Y6M7LH/) 24 | - Windows 10 System Programming - Part 2, by Pavel Yosifovich. [URL](https://www.amazon.com/Windows-10-System-Programming-Part/dp/B09GJKKBZP/) 25 | - Windows Kernel Programming, by Pavel Yosifovich. [URL](https://www.amazon.com/Windows-Kernel-Programming-Pavel-Yosifovich/dp/1977593372/) 26 | - Windows Internals: System architecture, processes, threads, memory management, and more, Part 1 (Developer Reference), by Pavel Yosifovich, Mark Russinovich, David Solomon, and Alex Ionescu. [URL](https://www.amazon.com/Windows-Internals-Part-architecture-management/dp/0735684189/) 27 | - Windows Internals, Part 2 (Developer Reference), by Andrea Allievi, Mark Russinovich, Alex Ionescu, and David Solomon. [URL](https://www.amazon.com/Windows-Internals-Part-2-7th/dp/0135462401/) 28 | - Operating Systems: Three Easy Pieces, by Remzi Arpaci-Dusseau and Andrea Arpaci-Dusseau. [URL](https://pages.cs.wisc.edu/~remzi/OSTEP/) 29 | 30 | 31 | --- 32 | 33 | 34 | - [x] Python Code for testing 35 | - [x] Add courses 36 | - [x] Add books 37 | - [ ] Update the content 38 | - [ ] Others? 39 | 40 | 41 | -------------------------------------------------------------------------------- /cpuBoundProcesses1.py: -------------------------------------------------------------------------------- 1 | from multiprocessing import Process, Queue 2 | 3 | def worker(inQ, outQ): 4 | while True: 5 | l = inQ.get() 6 | sumL = sum(l) 7 | outQ.put( sumL ) 8 | 9 | 10 | inQ = Queue() 11 | outQ = Queue() 12 | 13 | #creating a single new process 14 | #p = Process(target=worker, args=(inQ, outQ)) 15 | #p.start() 16 | 17 | #Creating 10 new processes 18 | #use ps -eLf to show them with grep for sure :) 19 | numWorkers = 10 20 | processList = [Process(target=worker, args=(inQ, outQ)) for i in range(numWorkers)] 21 | 22 | for process in processList: 23 | process.start() -------------------------------------------------------------------------------- /cpuBoundThread1.py: -------------------------------------------------------------------------------- 1 | from queue import Queue 2 | from threading import Thread 3 | 4 | inQ = Queue() 5 | outQ = Queue() 6 | 7 | def worker(): 8 | while True: 9 | l = inQ.get() 10 | sumL = sum(l) 11 | outQ.put(sumL) 12 | 13 | numWorkers = 10 14 | ts = [Thread(target=worker) for i in range(numWorkers)] 15 | 16 | for t in ts: 17 | t.start() -------------------------------------------------------------------------------- /fib1.py: -------------------------------------------------------------------------------- 1 | import time 2 | import itertools 3 | 4 | def fab(): 5 | l1=1; yield 1 6 | l2=1; yield 1 7 | while(True): 8 | l=l1+l2; 9 | yield l 10 | l1, l2 = l2, l 11 | 12 | l=fab() 13 | for i in l: 14 | print i 15 | time.sleep(1) 16 | -------------------------------------------------------------------------------- /fibonacciThreadServer.py: -------------------------------------------------------------------------------- 1 | from socket import * 2 | from threading import Thread 3 | import datetime 4 | 5 | def FibonacciTCPServer(address): 6 | '''Main Fibonacci TCP Server''' 7 | ServerSocket = socket(AF_INET, SOCK_STREAM) 8 | ServerSocket.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 9 | ServerSocket.bind(address) 10 | ServerSocket.listen(5) 11 | while True: 12 | ClientSocket, ClientAddress = ServerSocket.accept() 13 | print("\n[+] New Connection Started With: ", ClientAddress) 14 | Thread(target=FibonacciThreadHandler, args=(ClientSocket,), daemon=True).start() 15 | 16 | def FibonacciGenerator(iterations): 17 | '''Fibonacci Series Generator''' 18 | l1=1; yield 1 19 | l2=1; yield 1 20 | for i in range(2,iterations): 21 | l=l1+l2 22 | yield l 23 | l1, l2 = l2, l 24 | 25 | def FibonacciThreadHandler(ClientSock): 26 | '''Fibonacci Thread Handler''' 27 | while True: 28 | ClientRequest = ClientSock.recv(100) 29 | if not ClientRequest: 30 | break 31 | intClientRequest = int(ClientRequest) 32 | TimeBeforeGenerator = datetime.datetime.now() 33 | results=list(FibonacciGenerator(intClientRequest)) 34 | TimeAfterGenerator = datetime.datetime.now() 35 | TimeDifference = TimeAfterGenerator - TimeBeforeGenerator 36 | print("[+]") 37 | print("[+] The calculation of fibonacci(%d) took the following:" % intClientRequest) 38 | print("[+] \t%d days" % TimeDifference.days) 39 | print("[+] \t%d seconds" % TimeDifference.seconds) 40 | print("[+] \t%d microseconds" % TimeDifference.microseconds) 41 | print("[+] =====================================================") 42 | response = str(results[intClientRequest-1]).encode('ascii') + b'\n' 43 | ClientSock.send(response) 44 | print("[+] Connection Closed !!!") 45 | 46 | # Main Python Program 47 | if __name__ == "__main__": 48 | ListeningPort = 30001 49 | print("[+] =====================================================") 50 | print("[+] \tStarting Fibonacci Multi-Threading Server") 51 | print("[+] \tListening for New Connections on Port %d" % ListeningPort) 52 | print("[+] ") 53 | print("[+] \tUse netcat/ncat to Connect to Server") 54 | print("[+] \tExample (Windows Version) --> nc.exe 127.0.0.1 %d" % ListeningPort) 55 | print("[+] \tExample (Linux Version) --> nc 127.0.0.1 %d" % ListeningPort) 56 | print("[+] =====================================================") 57 | FibonacciTCPServer(('',ListeningPort)) 58 | -------------------------------------------------------------------------------- /fork1.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def child(): 4 | print('\nA new child ', os.getpid()) 5 | os._exit(0) 6 | 7 | def parent(): 8 | while True: 9 | newpid = os.fork() 10 | if newpid == 0: 11 | child() 12 | else: 13 | pids = (os.getpid(), newpid) 14 | print("parent: %d, child: %d\n" % pids) 15 | reply = input("q for quit / c for new fork") 16 | if reply == 'c': 17 | continue 18 | else: 19 | break 20 | 21 | parent() 22 | -------------------------------------------------------------------------------- /grabURLsThreads.py: -------------------------------------------------------------------------------- 1 | import xml.etree.ElementTree as etree 2 | import requests 3 | import time 4 | import queue, threading 5 | 6 | 7 | URLFeeds = ["URL1", 8 | "URL2", 9 | "URL3", 10 | "URL4"] 11 | 12 | def get_info_from_url(feed_url): 13 | xml = requests.get(feed_url).text 14 | tree = etree.fromstring(xml) 15 | name = tree.find(".//location").text 16 | temperature = tree.find(".//temperature_string").text 17 | time.sleep(1.5) 18 | return name, temperature 19 | 20 | if __name__ == "__main__": 21 | now = time.ctime() 22 | print ("Current temperature at %s" % now) 23 | print ("_" * 12) 24 | for feed in URLFeeds: 25 | name, temperature = get_info_from_url(feed) 26 | print ("\t%s : %s" % (name,temperature)) 27 | print("") 28 | print("Script ended at ", time.ctime()) 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /ioBoundProcesses1.py: -------------------------------------------------------------------------------- 1 | from multiprocessing import Process, Queue 2 | import requests 3 | 4 | def worker(inQ, outQ): 5 | while True: 6 | url = inQ.get() 7 | resp = requests.get(url) 8 | outQ.put((url, resp.status_code, resp.text)) 9 | 10 | 11 | inQ = Queue() 12 | outQ = Queue() 13 | 14 | #creating a single new process 15 | #p = Process(target=worker, args=(inQ, outQ)) 16 | #p.start() 17 | 18 | #Creating 10 new processes 19 | #use ps -eLf to show them with grep for sure :) 20 | numWorkers = 10 21 | processList = [Process(target=worker, args=(inQ, outQ)) for i in range(numWorkers)] 22 | 23 | for process in processList: 24 | process.start() -------------------------------------------------------------------------------- /ioBoundThread1.py: -------------------------------------------------------------------------------- 1 | from queue import Queue 2 | from threading import Thread 3 | import requests 4 | 5 | inQ = Queue() 6 | outQ = Queue() 7 | 8 | def worker(): 9 | while True: 10 | url = inQ.get() 11 | resp = requests.get(url) 12 | outQ.put((url, resp.status_code, resp.text)) 13 | 14 | numWorkers = 10 15 | ts = [Thread(target=worker) for i in range(numWorkers)] 16 | 17 | for t in ts: 18 | t.start() -------------------------------------------------------------------------------- /mappool1.py: -------------------------------------------------------------------------------- 1 | #import urllib2 2 | import urllib.request 3 | from multiprocessing.dummy import Pool as ThreadPool 4 | 5 | urls = [ 6 | 'http://www.python.org', 7 | 'http://www.python.org/about/', 8 | # 'http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html', 9 | # 'http://www.python.org/doc/', 10 | # 'http://www.python.org/download/', 11 | # 'http://www.python.org/getit/', 12 | # 'http://www.python.org/community/', 13 | # 'https://wiki.python.org/moin/', 14 | ] 15 | 16 | # Make the Pool of workers 17 | pool = ThreadPool(4) 18 | 19 | # Open the urls in their own threads 20 | # and return the results 21 | results = pool.map(urllib.request.urlopen, urls) 22 | #results = pool.map(urllib2.urlopen, urls) 23 | 24 | print(results) 25 | for i in results: 26 | print(i.headers) 27 | 28 | #close the pool and wait for the work to finish 29 | pool.close() 30 | pool.join() 31 | -------------------------------------------------------------------------------- /multiprocess2.py: -------------------------------------------------------------------------------- 1 | import multiprocessing as mp 2 | 3 | def washer(dishes, output): 4 | for dish in dishes: 5 | print('Washing', dish, 'dish') 6 | output.put(dish) 7 | 8 | def dryer(input): 9 | while True: 10 | dish = input.get() 11 | print('Drying', dish, 'dish') 12 | input.task_done() 13 | 14 | dish_queue = mp.JoinableQueue() 15 | dryer_proc = mp.Process(target=dryer, args=(dish_queue,)) 16 | dryer_proc.daemon = True 17 | dryer_proc.start() 18 | dishes = ['salad', 'bread', 'entree', 'dessert'] 19 | washer(dishes, dish_queue) 20 | dish_queue.join() 21 | -------------------------------------------------------------------------------- /multiprocessing1.py: -------------------------------------------------------------------------------- 1 | import multiprocessing as mp 2 | import random 3 | import string 4 | 5 | # Define an output queue 6 | output = mp.Queue() 7 | 8 | # define a example function 9 | def rand_string(length, output): 10 | """ Generates a random string of numbers, lower- and uppercase chars. """ 11 | rand_str = ''.join(random.choice( 12 | string.ascii_lowercase 13 | + string.ascii_uppercase 14 | + string.digits) 15 | for i in range(length)) 16 | output.put(rand_str) 17 | 18 | # Setup a list of processes that we want to run 19 | processes = [mp.Process(target=rand_string, args=(500, output)) for x in range(4)] 20 | 21 | # Run processes 22 | for p in processes: 23 | p.start() 24 | 25 | # Exit the completed processes 26 | for p in processes: 27 | p.join() 28 | 29 | # Get process results from the output queue 30 | results = [output.get() for p in processes] 31 | 32 | print(results) 33 | -------------------------------------------------------------------------------- /queue1.py: -------------------------------------------------------------------------------- 1 | from queue import Queue 2 | 3 | 4 | my_list = [] 5 | my_list.append(1) 6 | my_list.append(2) 7 | my_list.append(3) 8 | print (my_list.pop(0)) 9 | # Outputs: 1 10 | 11 | print (my_list) 12 | 13 | 14 | my_queue = Queue(maxsize=0) 15 | my_queue.put(1) 16 | my_queue.put(2) 17 | my_queue.put(3) 18 | print (my_queue.get()) 19 | my_queue.task_done() 20 | # Outputs: 1 21 | 22 | #print (my_queue.) 23 | 24 | for i in my_queue._get(): 25 | print (i) -------------------------------------------------------------------------------- /subprocess1.py: -------------------------------------------------------------------------------- 1 | __author__ = 'binary' 2 | import subprocess as sp 3 | 4 | fh = open('file','w') 5 | sp.call(['ls','-la'], stdout=fh) 6 | fh.close() 7 | sp.call(['ls','-la'], shell=True) 8 | 9 | x = sp.check_output(['echo','hello class']) 10 | print (x) 11 | 12 | sp.check_output('exit 0', shell=True) 13 | 14 | errFile = open('errorFile','w') 15 | sp.check_output('ls nosuchfile; exit 0', shell=True, stderr=errFile) 16 | errFile.close() 17 | 18 | child = sp.Popen('gedit') 19 | print (child) 20 | 21 | print (child.poll()) 22 | 23 | terminate = input('do u want to terminate the process? (y/n): ') 24 | if terminate == 'y': 25 | child.terminate() # can use .kill() too 26 | print (child.poll()) 27 | else: 28 | print ('child is running') 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /threadChat.py: -------------------------------------------------------------------------------- 1 | from socket import * 2 | from threading import Thread 3 | 4 | def clientHandler(): 5 | conn, addr = s.accept() 6 | print (addr, " is connected") 7 | while True: 8 | data = conn.recv(1024) 9 | if not data: 10 | break 11 | print("Received the message: ", repr(data)) 12 | conn.send(data) 13 | 14 | HOST='' 15 | PORT = 9091 16 | 17 | s = socket(AF_INET, SOCK_STREAM) 18 | s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 19 | s.bind((HOST,PORT)) 20 | s.listen(5) 21 | 22 | print ("The server is now running!") 23 | 24 | for i in range(5): 25 | Thread(target=clientHandler(), daemon=True).start() 26 | 27 | # while True: 28 | # clientSock, addr = s.accept() 29 | # print (addr, " is connected") 30 | # Thread(clientHandler, args=(clientSock,), daemon=True).start() 31 | 32 | s.close() 33 | -------------------------------------------------------------------------------- /threadFib.py: -------------------------------------------------------------------------------- 1 | from socket import * 2 | from threading import Thread 3 | import time 4 | import datetime 5 | import itertools 6 | 7 | def fibonacci1(n): 8 | '''fibonacci using recursive method''' 9 | if n <= 2: 10 | return 1 11 | else: 12 | return fibonacci1(n-1) + fibonacci1(n-2) 13 | 14 | def fibonacci2(n): 15 | '''fibonacci using iterative method ''' 16 | a, b = 0, 1 17 | for item in range(n): 18 | a, b = b, a + b 19 | return a 20 | 21 | def fib_server(address): 22 | sock = socket(AF_INET, SOCK_STREAM) 23 | sock.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 24 | sock.bind(address) 25 | sock.listen(5) 26 | while True: 27 | client, addr = sock.accept() 28 | print("[+] Connection started with: ", addr) 29 | #Thread(target=fib_handler, args=(client,), daemon=True).start() 30 | Thread(target=fib_handler_yield, args=(client,), daemon=True).start() 31 | 32 | def fib_handler(client): 33 | while True: 34 | req = client.recv(100) 35 | if not req: 36 | break 37 | n = int(req) 38 | result = fibonacci(n) # using the unefficient fibo 39 | resp = str(result).encode('ascii') + b'\n' 40 | client.send(resp) 41 | print("[+] Connection Closed !!!") 42 | 43 | def fibonacci_yield(n): 44 | l1=1; yield 1 45 | l2=1; yield 1 46 | for i in range(2,n): 47 | l=l1+l2; 48 | yield l 49 | l1, l2 = l2, l 50 | 51 | def fib_handler_yield(client): 52 | while True: 53 | req = client.recv(100) 54 | if not req: 55 | break 56 | n = int(req) 57 | a = datetime.datetime.now() 58 | results=list(fibonacci_yield(n)) 59 | #results = itertools.islice(l, n) 60 | b = datetime.datetime.now() 61 | diff = b - a 62 | print ("the calc took: %d days" % diff.days) 63 | print ("the calc took: %d seconds" % diff.seconds) 64 | print ("the calc took: %d microseconds" % diff.microseconds) 65 | 66 | resp = str(results[n-1]).encode('ascii') + str(diff.microseconds).encode('ascii') + b'\n' 67 | client.send(resp) 68 | print("[+] Connection Closed !!!") 69 | 70 | #for i in itertools.islice(l, 100): 71 | # print (i) 72 | fib_server(('',25001)) 73 | 74 | #x = fibonacci_yield(n) 75 | #print(x.__next__()) -------------------------------------------------------------------------------- /threading1.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | mydata = threading.local() 4 | mydata.x = 1 5 | 6 | def ThreadFunction(x): 7 | print ('running thread function: ', x) 8 | return 9 | 10 | if __name__ == '__main__': 11 | for i in range(5): 12 | #t = threading.Thread(target=ThreadFunction(i)) 13 | # Another way of passing arguments 14 | t = threading.Thread(target=ThreadFunction, args=(i,)) 15 | t.start() 16 | 17 | import matplotlib.pyplot as plt 18 | vals = [3,2,5,0,1] 19 | plt.plot(vals) -------------------------------------------------------------------------------- /threading1a.py: -------------------------------------------------------------------------------- 1 | from threading import Thread 2 | 3 | def myfunc(): 4 | print ("hello, world!") 5 | 6 | thread1 = Thread(target=myfunc) 7 | thread1.start() 8 | thread1.join() 9 | 10 | from threading import Thread 11 | 12 | class MyThread(Thread): 13 | def run(self): 14 | print ("I am a thread!") 15 | 16 | foobar = MyThread() 17 | foobar.start() 18 | foobar.join() -------------------------------------------------------------------------------- /threading2.py: -------------------------------------------------------------------------------- 1 | from threading import Thread 2 | from operator import add 3 | import random 4 | 5 | class Bank(object): 6 | def __init__(self, naccounts, ibalance): 7 | self._naccounts = naccounts 8 | self._ibalance = ibalance 9 | self.accounts = [] 10 | for n in range(self._naccounts): 11 | self.accounts.append(self._ibalance) 12 | 13 | def size(self): 14 | return len(self.accounts) 15 | 16 | def getTotalBalance(self): 17 | return reduce(add, self.accounts) 18 | 19 | def transfer(self, name, afrom, ato, amount): 20 | if self.accounts[afrom] < amount: return 21 | 22 | self.accounts[afrom] -= amount 23 | self.accounts[ato] += amount 24 | 25 | print ("%-9s %8.2f from %2d to %2d Balance: %10.2f" % \ 26 | (name, amount, afrom, ato, self.getTotalBalance())) 27 | 28 | class transfer(Thread): 29 | def __init__(self, bank, afrom, maxamt): 30 | Thread.__init__(self) 31 | self._bank = bank 32 | self._afrom = afrom 33 | self._maxamt = maxamt 34 | 35 | def run(self): 36 | for i in range(0, 3000): 37 | ato = random.choice(range(b.size())) 38 | amount = round((self._maxamt * random.random()), 2) 39 | self._bank.transfer(self.getName(), self._afrom, ato, amount) 40 | 41 | naccounts = 100 42 | initial_balance = 1000 43 | 44 | b = Bank(naccounts, initial_balance) 45 | 46 | threads = [] 47 | for i in range(0, naccounts): 48 | threads.append(transfer(b, i, 100)) 49 | threads[i].start() 50 | 51 | for i in range(0, naccounts): 52 | threads[i].join() -------------------------------------------------------------------------------- /threading3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from threading import Thread 4 | from processing import Process 5 | 6 | class threads_object(Thread): 7 | def run(self): 8 | function_to_run() 9 | 10 | class nothreads_object(object): 11 | def run(self): 12 | function_to_run() 13 | 14 | class process_object(Process): 15 | def run(self): 16 | function_to_run() 17 | 18 | def non_threaded(num_iter): 19 | funcs = [] 20 | for i in range(int(num_iter)): 21 | funcs.append(nothreads_object()) 22 | for i in funcs: 23 | i.run() 24 | 25 | def threaded(num_threads): 26 | funcs = [] 27 | for i in range(int(num_threads)): 28 | funcs.append(threads_object()) 29 | for i in funcs: 30 | i.start() 31 | for i in funcs: 32 | i.join() 33 | 34 | def processed(num_processes): 35 | funcs = [] 36 | for i in range(int(num_processes)): 37 | funcs.append(process_object()) 38 | for i in funcs: 39 | i.start() 40 | for i in funcs: 41 | i.join() 42 | 43 | def show_results(func_name, results): 44 | print "%-23s %4.6f seconds" % (func_name, results) 45 | 46 | if __name__ == "__main__": 47 | import sys 48 | from timeit import Timer 49 | 50 | repeat = 100 51 | number = 1 52 | 53 | num_threads = [ 1, 2, 4, 8 ] 54 | 55 | if len(sys.argv) < 2: 56 | print 'Usage: %s module_name' % sys.argv[0] 57 | print ' where module_name contains a function_to_run function' 58 | sys.exit(1) 59 | module_name = sys.argv[1] 60 | if module_name.endswith('.py'): 61 | module_name = module_name[:-3] 62 | print 'Importing %s' % module_name 63 | m = __import__(module_name) 64 | function_to_run = m.function_to_run 65 | 66 | print 'Starting tests' 67 | for i in num_threads: 68 | t = Timer("non_threaded(%s)" % i, "from __main__ import non_threaded") 69 | best_result = min(t.repeat(repeat=repeat, number=number)) 70 | show_results("non_threaded (%s iters)" % i, best_result) 71 | 72 | t = Timer("threaded(%s)" % i, "from __main__ import threaded") 73 | best_result = min(t.repeat(repeat=repeat, number=number)) 74 | show_results("threaded (%s threads)" % i, best_result) 75 | 76 | t = Timer("processed(%s)" % i, "from __main__ import processed") 77 | best_result = min(t.repeat(repeat=repeat, number=number)) 78 | show_results("processes (%s procs)" % i, best_result) 79 | print "\n", 80 | 81 | print 'Iterations complete' -------------------------------------------------------------------------------- /threading4.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | def do_this(what): 4 | whoami(what) 5 | 6 | def whoami(what): 7 | print("Thread %s says: %s" % (threading.current_thread(), what)) 8 | 9 | if __name__ == "__main__": 10 | whoami("I'm the main program") 11 | for n in range(4): 12 | p = threading.Thread(target=do_this,args=("I'm function %s" % n,)) 13 | p.start() -------------------------------------------------------------------------------- /threading5.py: -------------------------------------------------------------------------------- 1 | import threading, queue 2 | import time 3 | 4 | def washer(dishes, dish_queue): 5 | for dish in dishes: 6 | print ("Washing", dish) 7 | time.sleep(5) 8 | dish_queue.put(dish) 9 | 10 | def dryer(dish_queue): 11 | while True: 12 | dish = dish_queue.get() 13 | print ("Drying", dish) 14 | time.sleep(10) 15 | dish_queue.task_done() 16 | 17 | dish_queue = queue.Queue() 18 | for n in range(2): 19 | dryer_thread = threading.Thread(target=dryer, args=(dish_queue,)) 20 | dryer_thread.start() 21 | 22 | dishes = ['salad', 'bread', 'entree', 'desert'] 23 | washer(dishes, dish_queue) 24 | dish_queue.join() 25 | 26 | -------------------------------------------------------------------------------- /threads4.py: -------------------------------------------------------------------------------- 1 | from queue import Queue 2 | from threading import Thread 3 | 4 | 5 | 6 | def do_stuff(q): 7 | while True: 8 | print (q.get()) 9 | q.task_done() 10 | 11 | 12 | q = Queue(maxsize=0) 13 | num_threads = 10 14 | 15 | for i in range(num_threads): 16 | worker = Thread(target=do_stuff, args=(q,)) 17 | worker.setDaemon(True) 18 | worker.start() 19 | 20 | ''' 21 | for x in range(100): 22 | q.put(x) 23 | 24 | q.join() 25 | ''' 26 | 27 | for y in range (10): 28 | for x in range(100): 29 | q.put(x + y * 100) 30 | q.join() 31 | print ("Batch " + str(y) + " Done") 32 | 33 | 34 | --------------------------------------------------------------------------------