1.多线程的使用
(1)把一个函数按子线程的方式执行
from threading import Thread
t = Thread(target=func, args=(x,)) # 创建线程 target=函数名 args=函数的参数(放入的是实参)
t.setDaemon(True) # 主线程守护 只要主线程的任务执行完 程序就结束
# 查看当前任务是由哪个线程执行的
threading.current_thread()
# 查看运行的程序有的运行的线程列表
threading.enumerate()
# 查看运行的程序有多少个线程在运行
len(threading.enumerate())
threading.active_count()
t.join() # 线程同步(一个线程执行任务完成 下个线程再执行任务)
t.start() # 启动线程执行任务
(2)自定义线程类
class MyThread(threading.Thread):
def __init__(self, name):
# 如果自定义线程中重写init方法 子类需要调用父类同名方法
super(MyThread, self).__init__()
# 属性
self.name = name
def work1(self):
print(threading.current_thread())
print(self.name, "工作1")
def work2(self):
print(threading.current_thread())
print(self.name, "工作2")
# 如果自定义线程 使用线程执行多任务
# 必须实现一个方法名叫做run的方法
def run(self):
print(threading.current_thread())
self.work1()
self.work2()
if __name__ == '__main__':
# 创建一个子线程 (自定义线程类)
my_thread = MyThread("自定义线程")
# 启动线程
my_thread.start()
2.多线程共享全局变量问题
- 在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
- 线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)
- 如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确
3.互斥锁
threading模块中定义了Lock类,可以方便的处理锁定:
# 创建锁
mutex = threading.Lock()
# 锁定
mutex.acquire()
# 释放
mutex.release()
注意:
- 如果这个锁之前是没有上锁的,那么acquire不会堵塞
- 如果在调用acquire对这个锁上锁之前 它已经被 其他线程上了锁,那么此时acquire会堵塞,直到这个锁被解锁为止
锁的好处:
- 确保了某段关键代码只能由一个线程从头到尾完整地执行
锁的坏处:
- 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
- 由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁