This article discusses Python multi-threaded programming. Compiled from the website tutorialspoint.com (Make this article a memo). Running multiple threads is like running several different programs at the same time, but it’s useful:
- Each thread can share the memory with the main thread and can communicate with each other.
- Threads are smaller processes because they consume less memory than process calls.
Thread is a processor. When the thread starts The work will be in the order in which it is finished. In thread execution, there is a pointer variable of the command being processed, where
- Threads can be pre-empted or interrupted.
- Thread can be stopped while another thread is running (called yielding).
Threads are divided into two types:
- Kernel thread is a part of OS
- User thread
Threads supported by Python3
Python 3 supports both new and old threads with two classes:
- _thread for thread compatibility from older versions of Python.
- threading is designed for use with Python 3 and is a low-level thread.
In Python, the thread is a class that covers threading.
Thread creation can be done using the following build pattern:
_thread.start_new_thread( function, args [ , kwargs ] )
An example of creating two threads with the names thread-1 and thread-2 caused by the execution of the function print_time, but with the difference that thread-1 passes the value of 2 for the delay and thread- 2 passed a value of 4. So both threads are running with different delay values.
# -*- coding: UTF-8 -*- import _thread import time def print_time( thread_name, delay ): count = 0 while count < 5: time.sleep( delay ) count += 1 print(thread_name + str(time.ctime(time.time()))) def main(): try: _thread.start_new_thread( print_time, ("thread-1", 2)) _thread.start_new_thread( print_time, ("thread-2", 4)) except: print("Error: unable to start thread") while True: pass if __name__=="__main__": main()
The sample result when running on Raspberry Pi 3 is as shown in Figure 1.
Methods supported by threading are:
- threading.activeCount() returns the total number of threads created.
- threading.currentThread() returns the number of threads created by the current thread.
- threading.enumerate() returns a list of active threads.
Thread methods are:
- run() is the starting point of the thread.
- start() is a startup method called by run() .
- join([time]) wait until the thread terminates.
- isAlive() check if the thread is running.
- getName() returns the name of the thread.
- setName() give the thread a name.
Creating a thread from the following example’s threading class inherits three parts:
- Create a subclass named myThread that inherits from the Thread class.
- overwrite method init( self [, args] )
- overwrite method run( self [, args] ) to write the section to do when the thread starts.
# -*- coding: UTF-8 -*- import threading import time class myThread(threading.Thread): def __init__( self, thread_id, name, counter ): threading.Thread.__init__( self ) self.thread_id = thread_id self.name = name self.counter = counter def run( self ): print("Starting "+self.name) print_time( self.name, self.counter, 5 ) print("Exit "+self.name) running = 0 def print_time( thread_name, delay, counter ): while counter: if running: thread_name.exit() time.sleep(delay) print(thread_name +":"+str(time.ctime(time.time()))) counter -= 1 def main(): thread1 = myThread(1, "thread-1", 1) thread2 = myThread(2, "thread-2", 2) thread1.start() thread2.start() thread1.join() thread2.join() print("Exiting Main Thread") if __name__=="__main__": main()
An example of working results on Raspberry Pi 3 is shown in Figure 2.
Python 3 has a Lock() method that makes it easier to synchronize threads. A blocking parameter can be passed to a locked thread to control whether to wait or not wait from the lock.
- If blocking is 0, the thread returns 0 when blocking fails, and 1 if locking succeeds.
- If blocking is 1, the thread is blocked and waits until the lock is cancelled.
and the release() method is used to unlock the thread. As an example of the following program.
# -*- coding: UTF-8 -*- import threading import time thread_lock = threading.Lock() threads =  def print_time( thread_name, delay, counter ): while counter: time.sleep(delay) print(thread_name +":"+str(time.ctime(time.time()))) counter -= 1 class myThread(threading.Thread): def __init__( self, thread_id, name, counter ): threading.Thread.__init__( self ) self.thread_id = thread_id self.name = name self.counter = counter def run( self ): print("Starting "+self.name) thread_lock.acquire() print_time( self.name, self.counter, 5 ) thread_lock.release() def main(): # Create new threads thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() # Add threads to thread list threads.append(thread1) threads.append(thread2) # Wait for all threads to complete for t in threads: t.join() print("Exiting Main Thread") if __name__=="__main__": main()
An example of the result of working on Raspberry Pi 3 is shown in Figure 3.
Multi-threaded Priority Queue
Multi-threaded priority queues is the application of a queue-threaded data structure that enables an unlimited number of threads to be handled (Depending on the amount of memory available), the method for controlling the queue is as follows.
- get() removes an item from the queue
- put() adds item to the queue
- qsize() returns the number of items in the queue.
- empty() checks the status of the queue if the queue is empty or not.
- full() checks whether the queue status is full or not.
An example program of using a multi-threaded priority queue is as follows.
# -*- coding: UTF-8 -*- import threading import time import queue running = 1 thread_list = ["Thread-1", "Thread-2", "Thread-3"] name_list = ["One", "Two", "Three", "Four", "Five"] queue_lock = threading.Lock() work_queue = queue.Queue(10) threads =  thread_ID = 1 def process_data(thread_name, q): while running: queue_lock.acquire() if not work_queue.empty(): data = q.get() queue_lock.release() print( thread_name+" processing "+data) else: queue_lock.release() time.sleep(1) class myThread(threading.Thread): def __init__( self, thread_id, name, q ): threading.Thread.__init__( self ) self.thread_id = thread_id self.name = name self.q = q def run( self ): print("Starting "+self.name) process_data(self.name, self.q) print("Exit "+self.name) for t_name in thread_list: thread = myThread(thread_ID, t_name, work_queue) thread.start() threads.append(thread) thread_ID += 1 queue_lock.acquire() for word in name_list: work_queue.put(word) queue_lock.release() while not work_queue.empty(): pass running = False for t in threads: t.join() print ("Exiting Main Thread") thread_lock = threading.Lock() threads = 
An example of the result of working from the above code with Raspberry Pi 3 is shown in Figure 4.
All of them are of the different types of threads supported by Python version 3 and some basic usage examples for further study. It is found that nowadays there are many additional resources and languages. Therefore, programming students must adapt to the rapid changes and study from various sources regularly. And we will bring the articles compiled during the reading of these documents to be updated to read again. Finally, have fun with programming.
If you want to talk with us, feel free to leave comments below!!
- Tutorialspoint.com : Python-Multithreaded programming
From Python-Multithread programming By Jarut busarathid and Danai Jedsadathitikul