- Mastering Concurrency in Python
- Quan Nguyen
- 847字
- 2021-06-10 19:24:01
An example in Python
To illustrate the concept of running multiple threads in the same process, let's look at a quick example in Python. If you have already downloaded the code for this book from the GitHub page, go ahead and navigate to the Chapter03 folder. Let's take a look at the Chapter03/my_thread.py file, as follows:
# Chapter03/my_thread.py
import threading
import time
class MyThread(threading.Thread):
def __init__(self, name, delay):
threading.Thread.__init__(self)
self.name = name
self.delay = delay
def run(self):
print('Starting thread %s.' % self.name)
thread_count_down(self.name, self.delay)
print('Finished thread %s.' % self.name)
def thread_count_down(name, delay):
counter = 5
while counter:
time.sleep(delay)
print('Thread %s counting down: %i...' % (name, counter))
counter -= 1
In this file, we are using the threading module from Python as the foundation of the MyThread class. Each object of this class has a name and delay parameter. The function run(), which is called as soon as a new thread is initialized and started, prints out a starting message, and, in turn, calls the thread_count_down() function. This function counts down from the number 5 to the number 0, while sleeping between iterations for a number of seconds, specified by the delay parameter.
The point of this example is to show the concurrent nature of running more than one thread in the same program (or process) by starting more than one object of the MyThread class at the same time. We know that, as soon as each thread is started, a time-based countdown for that thread will also start. In a traditional sequential program, separate countdowns will be executed separately, in order (that is, a new countdown will not start until the current one finishes). As you will see, the separate countdowns for separate threads are executed concurrently.
Let's look at the Chapter3/example1.py file, as follows:
# Chapter03/example1.py
from my_thread import MyThread
thread1 = MyThread('A', 0.5)
thread2 = MyThread('B', 0.5)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print('Finished.')
Here, we are initializing and starting two threads together, each of which has 0.5 seconds as its delay parameter. Run the script using your Python interpreter. You should get the following output:
> python example1.py
Starting thread A.
Starting thread B.
Thread A counting down: 5...
Thread B counting down: 5...
Thread B counting down: 4...
Thread A counting down: 4...
Thread B counting down: 3...
Thread A counting down: 3...
Thread B counting down: 2...
Thread A counting down: 2...
Thread B counting down: 1...
Thread A counting down: 1...
Finished thread B.
Finished thread A.
Finished.
Just as we expected, the output tells us that the two countdowns for the threads were executed concurrently; instead of finishing the first thread's countdown and then starting the second thread's countdown, the program ran the two countdowns at almost the same time. Without including some overhead and miscellaneous declarations, this threading technique allows almost double improvement in speed for the preceding program.
There is one additional thing that should be taken note of in the preceding output. After the first countdown for number 5, we can see that the countdown of thread B actually got ahead of thread A in execution, even though we know that thread A was initialized and started before thread B. This change actually allowed thread B to finish before thread A. This phenomenon is a direct result of concurrency via multithreading; since the two threads were initialized and started almost simultaneously, it was quite likely for one thread to get ahead of the other in execution.
If you were to execute this script many times, it would be quite likely for you to get varying output, in terms of the order of execution and the completion of the countdowns. The following are two pieces of output that I obtained by executing the script again and again. The first output shows a uniform and unchanging order of execution and completion, in which the two countdowns were executed hand in hand. The second shows a case in which thread A was executed significantly faster than thread B; it even finished before thread B counted to number 1. This variation of output further illustrates the fact that the threads were treated and executed by Python equally.
The following code shows one possible output of the program:
> python example1.py
Starting thread A.
Starting thread B.
Thread A counting down: 5...
Thread B counting down: 5...
Thread A counting down: 4...
Thread B counting down: 4...
Thread A counting down: 3...
Thread B counting down: 3...
Thread A counting down: 2...
Thread B counting down: 2...
Thread A counting down: 1...
Thread B counting down: 1...
Finished thread A.
Finished thread B.
Finished.
The following is another possible output:
> python example1.py
Starting thread A.
Starting thread B.
Thread A counting down: 5...
Thread B counting down: 5...
Thread A counting down: 4...
Thread B counting down: 4...
Thread A counting down: 3...
Thread B counting down: 3...
Thread A counting down: 2...
Thread B counting down: 2...
Thread A counting down: 1...
Finished thread A.
Thread B counting down: 1...
Finished thread B.
Finished.
- Bootstrap Site Blueprints Volume II
- R語言數據分析從入門到精通
- JavaScript高效圖形編程
- Spring Cloud Alibaba微服務架構設計與開發實戰
- SQL學習指南(第3版)
- Visual Basic程序開發(學習筆記)
- DevOps入門與實踐
- C#程序設計基礎:教程、實驗、習題
- Hands-On Automation Testing with Java for Beginners
- Corona SDK Mobile Game Development:Beginner's Guide(Second Edition)
- 時空數據建模及其應用
- Mastering Elasticsearch(Second Edition)
- 零代碼實戰:企業級應用搭建與案例詳解
- 從Power BI到Analysis Services:企業級數據分析實戰
- Greenplum構建實時數據倉庫實踐