基础概念
import time
def test(something):
print(f"我开始>>> {something}")
time.sleep(2)
print(f"我结束>>> {something}")
"""
场景:
1- io密集型--阻塞
sleep requests socket
"""
import threading
"""
threading.Thread(target=,args=)
target= 你这个带定义的线程要做的事情是什么 一般是一个函数或者方法 只能传递函数名
args= 这个函数或者方法需要传入的参数 是一个元组类型
"""
if name == 'main':
startTime = time.time()
#1- 创建线程
t1 = threading.Thread(target=test,args=("上课",))
t2 = threading.Thread(target=test, args=("喝水",))
#2- 启动线程
t1.start()
t2.start()
#主线程执行的时候,并没有去等待子线程t1 t2执行完成!
#希望,主线程退出前,检查下子线程是否运行完,子线程运行完,主线程再退出!
t1.join()
t2.join()
endTime = time.time()
print(f"耗时>>>{endTime-startTime} s")
计算密集型
def test():
num = 0
for one in range(10000000):
num += 1#num = num+1
import time
import threading
if name == 'main':
startTime = time.time()
test()# 0.36s
test()
endTime = time.time()
print(f"耗时-常规>>>{endTime - startTime} s")
startTime = time.time()
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
#2- 启动线程
t1.start()
t2.start()
t1.join()
t2.join()
endTime = time.time()
print(f"耗时-多线程>>>{endTime - startTime} s")
守护线程
import threading
import time
def test(something):
print(f"我开始>>> {something}")
time.sleep(3)
print(f"我结束>>> {something}")
if name == 'main':
startTime = time.time()
#1- 创建线程
t1 = threading.Thread(target=test,args=("上课",))
t2 = threading.Thread(target=test, args=("喝水",))
# t1.setDaemon(True)#守护线程,主线程想要结束,可以直接自己退出,子线程不在运行!!
# t2.setDaemon(True)
#2- 启动线程
t1.start()
t2.start()
# t1.join()
# t2.join()
for one in range(2):
print("主线程在运行!>>> ",one)
time.sleep(1)
endTime = time.time()
print(f"耗时>>>{endTime-startTime} s")
"""
使用场景:
1- 如果只有t1.start(),没有 t1.join() 和 t1.setDaemon(True)
效果: 所有线程全部运行完成,这样会出现,主线程结束后,子线程继续运行,直到结束!
2- 如果只有t1.start(),+t1.join() ,没有t1.setDaemon(True)
效果:主线程结束前会等待所有子线程运行完成,再结束!----阻塞
3- 如果有t1.setDaemon(True),t1.start(),没有t1.join() ----守护线程
效果: 主线程完成,所有子线程都中断
"""
死锁
import threading
import time
lockA = threading.Lock() # 面试官的锁
lockB = threading.Lock() # 小明的锁
面试官
def foo1():
lockA.acquire() # 上锁
print("请解释什么是死锁")
time.sleep(1)
lockB.acquire() # 上锁
print("发 offer")
time.sleep(1)
lockA.release() # 释放锁
lockB.release() # 释放锁
小明
def foo2():
lockB.acquire() # 上锁
print("请给我 offer")
time.sleep(1)
lockA.acquire() # 上锁
print("解释了什么是死锁")
time.sleep(1)
lockA.release() # 释放锁
lockB.release() # 释放锁
t1 = threading.Thread(target=foo1)
t2 = threading.Thread(target=foo2)
t1.start()
t2.start()
递归锁
import threading
import time
lockR = threading.RLock() # 递归锁
"""
递归锁内部维护着一把锁和一个计数器
每次上锁,计数器加一
每次解锁,计数器减一
计数器可以大于零也可以等于零,但不能小于零
"""
面试官
def foo1():
lockR.acquire() # 上锁
print("请解释什么是死锁")
time.sleep(1)
lockR.acquire() # 上锁
print("发 offer")
time.sleep(1)
lockR.release() # 释放锁
lockR.release() # 释放锁
小明
def foo2():
lockR.acquire() # 上锁
print("请给我 offer")
time.sleep(1)
lockR.acquire() # 上锁
print("解释了什么是死锁")
time.sleep(1)
lockR.release() # 释放锁
lockR.release() # 释放锁
t1 = threading.Thread(target=foo1)
t2 = threading.Thread(target=foo2)
t1.start()
t2.start()
协程
import time
import gevent# pip install gevent -i https://douban.xxxxx
from gevent import monkey
monkey.patch_all()
def f(num):
for i in range(0,2):
print(f"f{num}-正在运行>>> ",i)
time.sleep(2)
if name == 'main':
startTime = time.time()#开始计时
g1 = gevent.spawn(f,1)#创建协程
g2 = gevent.spawn(f,2)#创建协程
gevent.joinall([g1,g2])
endTime = time.time()
print(f"扫描过程,耗时>>> {endTime-startTime}s")
举例 - 银行业务
"""
原本卡里 1000RMB
1- 进账 +500
2- 支出 -200
"""
import time
import threading
lock = threading.Lock()
balance = 1000# 全余额
def test(num):
global balance# 使用全局变量
lock.acquire()#上锁
#使用自己一个变量存放这个余额
userBalance = balance
#进出帐操作
userBalance = userBalance + num
time.sleep(2) # 模拟处理时间
balance = userBalance
#释放锁
lock.release()
if name == 'main':
#1-进账 500RMB
t1 = threading.Thread(target=test,args=(500,))
#1-支出 -200RMB
t2 = threading.Thread(target=test,args=(-200,))
#开启
t1.start()
t2.start()
#阻塞主线程运行!
t1.join()
t2.join()
print("卡里余额>>> ",balance)
标签:python,t2,基础,t1,threading,线程,time,print,多线程
From: https://www.cnblogs.com/running-snail-12345/p/18263941