官术网_书友最值得收藏!

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.
主站蜘蛛池模板: 罗山县| 满城县| 怀安县| 湘潭县| 昭平县| 枞阳县| 简阳市| 德安县| 阿瓦提县| 西贡区| 商丘市| 嘉义县| 白城市| 西乡县| 卢湾区| 北流市| 额敏县| 高台县| 玉环县| 邹平县| 定结县| 天津市| 巴林左旗| 乌拉特后旗| 溆浦县| 天祝| 柳河县| 新营市| 佛坪县| 芒康县| 隆德县| 余庆县| 高碑店市| 灯塔市| 永昌县| 江永县| 蛟河市| 黄龙县| 工布江达县| 贡嘎县| 信丰县|