import threading 导入县城模块
Thread线程类参数:
- target:执行的任务名
- args: 以元组的形式给任务传参
- kwargs:以字典的形式给任务传参
多线程示例
import threading
import time
def sing(name):
print(f"{name}在唱歌")
time.sleep(2)
print("唱歌结束")
def dance(name):
print(f"{name}在跳舞")
time.sleep(2)
print("跳舞结束")
if __name__ == '__main__':
t1 = threading.Thread(target=sing, args=("张三",)) # 入参是以元组的形式入参,只有一个元素的时候后面要记得加','
t2 = threading.Thread(target=dance, args=("李四",))
t1.daemon = True # 设置t1为守护线程
t2.daemon = True # 设置t2为守护线程
t1.start()
t2.start()
t1.join() # 等待子线程结束
t2.join() # 等待子线程结束
print("表演结束")
---------------------------------
张三在唱歌
李四在跳舞
唱歌结束
跳舞结束
表演结束
守护线程必须在
start()之前设置,表示主线程执行结束 子线程也会跟着结束。
join()必须在start()之后执行,表示主线程会等待子线程执行完,主线程才继续执行
上面的案例如果不执行join()方法 主线程结束后就直接一波带走子线程了,根本不会输出唱歌结束跳舞结束
互斥锁
对共享数据进行锁定,保证多个线程访问共享数据不会出现数据错误问题:保证同一时间只能有一个线程去操作
方法:
acquire()上锁release()释放锁
这两个方法必须成对出现,不然容易形成死锁.
from threading import Lock
from threading import Thread
lock = Lock()
a = 0
b = 1000000
def add():
# 上锁
lock.acquire()
for i in range(b):
global a
a += 1
print('第一次累加:', a)
#释放锁
lock.release()
def add2():
lock.acquire()
for i in range(b):
global a
a += 1
print('第二次累加:', a)
lock.release()
if __name__ == '__main__':
t1 = Thread(target=add)
t2 = Thread(target=add2)
t1.start()
t2.start()
---------------------------------------------------
没有锁的话:
第一次累加: 1445094
第二次累加: 2000000
开启锁:
第一次累加: 1000000
第二次累加: 2000000
线程同步
1、join() 线程阻塞
2、互斥锁