Thread
创建子线程 多任务管理
多任务执行形式:
时间片轮转
优先级调用
CPU状态
并行:cpu核心数多于运行程序树
并发:轮换进行程序执行 常态
# 多任务
import threading
import time
def sing():
for i in range(5):
print("正在唱歌...")
time.sleep(1)
def dance():
for i in range(5):
print("正在跳舞...")
time.sleep(1)
def main():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
print(threading.enumerate())
t1.start()
print(threading.enumerate())
t2.start()
if __name__ == '__main__':
main()
注:target 目标方向
函数名() 调用函数
函数名 显示函数位置
enumerate 显示当前线程数量(另 标号用法)
线程之间的关系:
调用start时调用函数并创建子线程,函数结束子线程结束;
函数执行顺序不确定,可用time.sleep操作函数执行顺序;
子线程结束后主线程才会结束,子线程运行时主线程继续运行直到需要子线程结果;
join函数使主线程等待子线程结束后继续进行(除非下一步需要子线程结果,否则一般不用);
守护线程在主线程结束时无论是否结束都强制结束。
函数及类的多线程使用形式:
函数
t=threading.Thread(target=dance)
t.start()
t.join()
注:join 主线程等待子线程完成才继续运行,一般不用,主线程不用等待子线程
类
class MyThread(threading.Thread):
def run(self):
self.函数名()
t = MyThread()
t.start()
多线程共享全局变量两种形式
global声明:变量 global 指向改变
参数为可变类型:实参为列表、集合 指向不变
args传参 args=(元组,)
**互斥锁 **
多任务使用全局变量时使用,避免因共享全局变量而产生的资源竞争的问题
# 创建锁
mutex = threading.Lock()
# 锁定
mutex.acquire()
# 释放
mutex.release()
死锁:互锁
死锁实例
import threading
import time
#创建互斥锁,默认是没有上锁时
mutex_1 = threading.Lock()
mutex_2 = threading.Lock()
def test1():
print("in test1 lock 1")
mutex_1.acquire()
time.sleep(3)
mutex_2.acquire()
print("in test1 step lock 2")
mutex_1.release()
def test2():
print("in test2 lock 2")
mutex_2.acquire()
time.sleep(3)
mutex_1.acquire()
print("in test2 step lock 1")
mutex_1.release()
mutex_2.release()
if __name__ == '__main__':
t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
结果:
in test1 lock 1
in test2 lock 2
避免死锁的方法:
1.程序设计时尽量避免(银行家算法)
2.添加超时时间(timeout=)
mutex_2.acquire(timeout=1)