详解Python中的多线程、线程锁、线程变量|详解Python中的多线程、线程锁、线程变量 - threading、Thread、Lock与ThreadLocal详解
其他关于Python的总结文章请访问:https://www.jianshu.com/nb/47435944
详解Python中的多线程、线程锁、线程变量 - threading、Thread、Lock与ThreadLocal详解
关于多进程的内容请参考:<>
【详解Python中的多线程、线程锁、线程变量|详解Python中的多线程、线程锁、线程变量 - threading、Thread、Lock与ThreadLocal详解】一个进程可以包含多个线程,而且至少必须要有一个线程,这个线程被称为主线程,在Python中的名字为 MainThread
。进程与线程最大的不同在于,进程的信息时各自的,而(同一个进程下的)线程的信息是公用的,即他们都处理、使用所在进程的信息数据等。
可以使用Python中的threading
模块进行线程管理于操作。使用 threading.current_thread()
获取当前所在线程,使用线程实例的name
属性获取线程的名字。
使用Thread创建多线程
一个python运行起来后对应着一个进程,这个进程的的主线程即 MainThread
,使用Thread
可以创建新的线程,创建时使用参数 target
绑定线程运行的目标,使用 name
参数为线程定义一个名字。
Thread
的实例有的常用方法:
-
start
:开始执行这个线程 -
join
:等待线程执行结束
import time, random, threadingdef print_time():
time.sleep(random.random())
print("I'm thread {}, time now is {}".format(threading.current_thread().name, time.time()))print("The main thread is {}".format(threading.current_thread().name))
thread1 = threading.Thread(target=print_time, name="New Thread 1")
thread2 = threading.Thread(target=print_time, name="New Thread 2")
thread3 = threading.Thread(target=print_time, name="New Thread 3")thread1.start()
thread2.start()
thread3.start()thread1.join()
thread2.join()
thread3.join()
得到的结果是随机的:
The main thread is MainThread
I'm thread New Thread 3, time now is 1607256751.4239407
I'm thread New Thread 1, time now is 1607256751.8748183
I'm thread New Thread 2, time now is 1607256751.9063895
使用锁Lock修改数据 由于(同一个进程下的)多个线程使用的是同一套数据,所以如果多个线程同时访问一个数据就会造成冲突,解决的方法是使用线程锁,在某个线程修改这个数据的时候,它获得一把锁,只有获得锁的这个线程有权利修改这个数据,等修改完成后再释放锁,这样就可以保证在一个时间只有一个线程修改这个数据。如果多个线程都想请求得到锁,他们会排队获得。
Python中使用
threading.Lock
来完成,一个Lock
实例常用的的方法有:-
acquire
:请求获得锁 -
relaese
:释放锁
try...final...
语句,将释放锁的代码放在finally
块里。一个例子:一个线程要给一个数据加一,一个线程要给同一个数据减一:
import time, random, threadingnumber = 0
lock = threading.Lock()def add_one():
global number
for i in range(20):
lock.acquire()
print("I'm thread {}, I acquired the lock.".format(threading.current_thread().name))
try:
number += 1
finally:
lock.release()
print("I'm thread {}, I realised the lock.".format(threading.current_thread().name))def minus_one():
global number
for i in range(20):
lock.acquire()
print("I'm thread {}, I acquired the lock.".format(threading.current_thread().name))
try:
number -= 1
finally:
lock.release()
print("I'm thread {}, I realised the lock.".format(threading.current_thread().name))thread_add = threading.Thread(target=add_one, name="Thread ADD")
thread_minus = threading.Thread(target=minus_one, name="Thread MINUS")thread_add.start()
thread_minus.start()thread_add.join()
thread_minus.join()
使用ThreadLocal创建进程局部变量 设想如果有多个线程,它们都要处理自己的一个变量,但是又想进行对于该变量的信息交换,这样的情况下,可以使用一个全局变量来记录每个线程的局部变量(比如一个字典),显然是很麻烦的,于是可以使用
ThreadLocal
来处理线程的局部变量。一个例子:两个线程都有各自的变量
number
import threadinglocal_variable = threading.local()def print_number():
number = local_variable.number
print("I'm thread {}, I'm processing my number {}".format(threading.current_thread().name, number))def set_number(num):
local_variable.number = num
print_number()thread1 = threading.Thread(target=set_number, args=(1,), name="Thread 1")
thread2 = threading.Thread(target=set_number, args=(2,), name="Thread 2")thread1.start()
thread2.start()
thread1.join()
thread2.join()
得到的结果如下:
I'm thread Thread 1, I'm processing my number 1
I'm thread Thread 2, I'm processing my number 2
推荐阅读
- 热闹中的孤独
- JS中的各种宽高度定义及其应用
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- python学习之|python学习之 实现QQ自动发送消息
- Android中的AES加密-下
- 逻辑回归的理解与python示例
- 放下心中的偶像包袱吧
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- Java|Java OpenCV图像处理之SIFT角点检测详解