6. Thread¶
What is Thread?
A thread is a single sequential control flow in a program. A relatively independent and schedulable execution unit in the process, which is the basic unit of system independent scheduling and dispatching CPU refers to the scheduling unit of the running program. Run multiple threads simultaneously in a single program to complete different tasks, called multi-threading.
6.1. Create Thread¶
First to import the _thread
module, which will provide the functions needed. Please note that the module name is _thread
(the underscore here is not wrong).
We will also import the time
module, so we can use the sleep
function to introduce some delay in our program.
import _thread
import time
Next, we will define the function executed in the thread. Simply loop iteratively 5 times the current running time of printing, each loop will have a certain delay.
We will use the sleep
aspect of the time
module mentioned above to introduce the delay, and the time
module receives the delay in seconds as input. The pararmeter of delay
is the delay in seconds for a single iteration loop.
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s sec" % ( threadName, time.localtime()[5] ))
print("%s:End" %threadName)
# exit thread
_thread.exit()
To start our thread, we simply call the start_new_thread function of the _thread module, specify the first parameter as the _thread module, specify the first parameter as the print_time
function we defined earlier, and specify it as a 2-tuple corresponding to the thread function parameters.
_thread.start_new_thread( print_time, ("Thread-1", 2, ) )
_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
Finally, use the while
conditional judgment to make the program in an infinite loop without executing any instructions:
while True:
pass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import _thread # 导入线程模块
import time # 导入时间模块
# 定义线程函数,打印线程编号和运行时间
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s sec" % ( threadName, time.localtime()[5] ))
print("%s:End" %threadName)
# 结束线程
_thread.exit()
# 启动线程1
_thread.start_new_thread( print_time, ("Thread-1", 2, ) )
# 启动线程2
_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
while True: # 主体循环
pass # 空指令
|
The program execution will produce the following results:
Thread-1: 4 sec
Thread-1: 6 sec
Thread-2: 6 sec
Thread-1: 8 sec
Thread-1: 10 sec
Thread-2: 10 sec
Thread-1: 12 sec
Thread-1:End
Thread-2: 14 sec
Thread-2: 18 sec
Thread-2: 22 sec
Thread-2:End
Note
- Multi-threading seems to run in parallel at the same time. In fact, at a certain moment, a CPU core can only perform the tasks of one process.
- The current multi-process / multi-tasking of computers is actually achieved by accelerating the execution speed of the CPU. Because a CPU can execute hundreds of millions of calculations per second and can switch processes many times, so it can be perceived by humans. In time, it seems that it is actually executing at the same time.
6.2. Thread Lock¶
In multithreading, all variables are shared by all threads, so any variable can be modified by any thread. Therefore, the biggest danger of sharing data between threads is that multiple threads change a variable at the same time, and the content is messed up. Lets learn the control to access shared resources. Control is necessary to prevent data corruption. In other words, in order to prevent simultaneous access to the object, we need to use the Lock object.
Thread lock has two states: Lock and Unlock . It was created in the state of Unlock . It has two basic methods,acquire()
and release()
.
When the state of the thread is Unlock , acquire()
changes the state to Lock and returns immediately.
When the state is Lock , acquire()
blocks until the call to release()
in another thread changes it to Unlock ,and then the acquire()
call changes it Reset to Lock and return.
Attention
The release()
method should only be called in the Lock state; It changes the state to Unlocked and returns immediately. If you try to release an unlocked lock, it will raise RuntimeError .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import _thread # 导入线程模块
import time # 导入时间模块
# 创建锁
lock=_thread.allocate_lock()
# 定义线程函数,打印线程编号和运行时间
def print_time( threadName, delay):
count = 0
# 获取锁
if lock.acquire():
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s sec" % ( threadName, time.localtime()[5] ))
# 释放锁
lock.release()
print("%s:End" %threadName)
# 结束线程
_thread.exit()
# 启动线程1
_thread.start_new_thread( print_time, ("Thread-1", 2, ) )
# 启动线程2
_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
while True: # 主体循环
pass # 空指令
|
Operation result:
Thread-1: 2 sec Thread-1: 4 sec Thread-1: 6 sec Thread-1: 8 sec Thread-1: 10 sec Thread-1:End Thread-2: 14 sec Thread-2: 18 sec Thread-2: 22 sec Thread-2: 26 sec Thread-2: 30 sec Thread-2:End
The advantage of locks is to ensure that a certain piece of critical code can only be executed completely by one thread from beginning to end. Of course, there are many disadvantages. First, it prevents multiple threads from executing concurrently. A piece of code that contains a lock can only be used in single-threaded mode Implementation, efficiency is greatly reduced.