Python多线程中Lock锁的使用与注意事项
本文详细解析Python中threading模块的Lock锁机制,通过对比加锁与未加锁的多线程执行结果,说明锁在防止共享资源竞争中的作用。同时指出threading.Lock()对multiprocessing多进程无效,并提供了相关代码示例及实现细节。
在多线程环境下使用Lock锁,可以有效避免多个线程在访问共享资源时产生混乱。例如,当创建多个线程并向一个空列表l中依次添加数字并打印当前列表状态时,若不加锁保护,可能会出现执行顺序交错的情况。
# encoding=utf8 import threading import time lock = threading.Lock() l = [] def test1(n): lock.acquire() l.append(n) print l lock.release() def test(n): l.append(n) print l def main(): for i in xrange(0, 10): th = threading.Thread(target=test, args=(i, )) th.start() if __name__ == '__main__': main()
运行结果示例如下:
[0] [0, 1] [0, 1, 2] [0, 1, 2, 3][ 0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4[, 05, , 16, , 27, ]3 , 4, 5, 6[, 07, , 18, ]2 , 3, 4, [50, , 61, , 72, , 83, , 94], 5, 6, 7, 8, 9]
造成上述“混乱”输出的原因是,每个线程同时执行test函数,向列表l追加数字并打印。由于没有同步机制,多个线程可能同时读取、修改或打印列表,导致输出顺序不可预测且格式错乱。
接下来,让每个线程调用经过加锁处理的“test1”函数,观察其运行结果:
[0] [0, 1] [0, 1, 2] [0, 1, 2, 3] [0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3, 4, 5, 6, 7, 8] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
此时的输出结果变得有序且清晰。这是因为在test1函数中,每次向列表l添加数字并打印之前,都会先调用锁机制。这确保了同一时刻只有一个线程能够执行添加和打印操作,从而避免了并发写入导致的冲突。
通过对比上述两种情况的结果可知,在多线程程序中,当需要“独占”访问共享资源时,必须使用锁来控制并发行为,以防止多个线程同时占用资源引发异常或数据错误。
使用锁时,首先调用acquire()方法,这相当于向其他线程声明“我正在占用该资源,请等待”;当资源使用完毕后,需调用release()方法,通知其他线程“我已释放资源,你们可以使用了”。
Python threading Lock
本文主要通过代码示例说明以下两点:
threading.Lock()不影响multiprocessing- .
threading.Lock()影响threading.
具体代码如下:
import threading
import time
from multiprocessing import Pool
_lock = threading.Lock()
def small_func(value):
"""
添加线程锁
:param value:
:return:
"""
print(value)
with _lock:
time.sleep(5)
return value
def no_small_func(value):
"""
没有线程锁
:param value:
:return:
"""
print(value)
# with _lock:
time.sleep(5)
return value
def main():
"""
multiprocessing 是基于进程的,因此线程锁对其不影响,
:return:
"""
st = time.time()
p = Pool(processes=4)
value = p.map(func=small_func, iterable=range(4))
et = time.time()
print(f"all use time: {et - st}")
print(value)
def main2():
"""
threading 受到 线程锁 影响
:return:
"""
st = time.time()
thread_list = []
for temp_value in range(4):
t = threading.Thread(target=small_func, args=(temp_value,))
t.start()
thread_list.append(t)
for i in thread_list:
i.join()
et = time.time()
print(f"all use time: {et - st}")
# print(value)
def main3():
st = time.time()
thread_list = []
res = []
for temp_value in range(4):
# 不加线程锁就行了
t = threading.Thread(target=no_small_func, args=(temp_value,))
t.start()
thread_list.append(t)
for i in thread_list:
v = i.join()
res.append(v)
et = time.time()
print(f"all use time: {et - st}")
print(res)
if __name__ == '__main__':
# main()
# main2()
main3()到此这篇关于Python threading中lock的使用的文章就介绍到这了,更多相关Python threading lock使用内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













