threading与Lock#
Python中实现多线程的方式有Thread和threading,其中Thread过于底层,threading是将Thread封装之后的,所以使用起来更加方便。
在Python的线程中,全局变量可以被进程中的线程访问和修改,这样就会造成一种数据不安全的状态,解决的方法有1)使用while True+if判断来实现控制其他线程的执行,但是此种方式过于消耗资源。在这里使用互斥锁的方式来解决这个问题
代码如下:
#coding=utf-8
from threading import Thread,Lock
import time,os
g_num = 0
def work1():
global g_num
for i in range(1000000):
#metux.acquire()
g_num += 1
#metux.release()
print('work1',g_num)
def work2():
global g_num
for i in range(1000000):
#metux.acquire()
g_num += 1
#metux.release()
print('work2',g_num)
if __name__ == '__main__':
#metux = Lock()
t1 = Thread(target = work1)
t2 = Thread(target = work2)
t1.start()
t2.start()
t1.join()
t2.join()
print(g_num)
此段代码中注释了metux对象的部分,这样的代码执行结果会是:
因为多个线程中g_num += 1在执行的时候,由于CPU切换进程的机制会导致有一些进程此步骤没有执行完毕,但是保留了当时执行的数据状态,所以会造成部分数据没有得到正确的加合运算。
针对这种情况的解决方式一种是使用互斥锁,即将上述代码中注释的部分解除掉,执行结果如下:
其中metux = Lock()初始化一个对象,metux.acquire()来进行上锁,metux.release()来进行解锁。当代码某处使用了一个锁之后,代码在执行别处时如果再遇到这个锁的时候,就会卡顿在锁的地方不会再往下执行
threading与thread.local()方法#
使用互斥锁,虽然保护了数据安全,但是从另一方面就是将多个进程改成了单一一个进程在运行。这样并不能很好的提高多线程的效率。
在这里Python的threading中有一个ThreadLocal方法,可以创建一个全局变量,但是多个线程只能修改自己对于此全局变量的那一个部分,做到了数据保护和线程运行
代码示例如下:
#coding=utf-8
import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student()
t1 = threading.Thread(target= process_thread, args=('dongGe',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('老王',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
运行结果如下:
Ubuntu中查看线程的方式#
-
ps -T -p PID
-
top -H -p PID
网友评论