python_多线程、线程锁、多进程与多线程适用场景
一。线程:threading
1)多线程
import threading
import time
def music(user):
print(f'{user} 正在运行函数1')
time.sleep(5)
print(f'{threading.current_thread().name} 函数1即将运行结束')
return user
def lol(user):
print(f'{user} 正在运行函数2')
time.sleep(8)
print(f'{threading.current_thread().name} 函数2即将运行结束')
return user
if __name__ == '__main__':
start = time.time()
t1 = threading.Thread(target=music, args=('函数1',), name='线程1')
t2 = threading.Thread(target=lol, args=('函数2',), name='线程2')
t1.start()
t2.start()
t1.join() #阻塞主程序,但不会阻塞线程2,若想阻塞程序2需要在 t1.start() 下一行执行 t1.join()
t2.join()
end = time.time()
print(f"运行时间为:{end - start}:.2f")
print("主程序运行结束")
运行结果,x线程1先与线程2结束,耗时时间为8秒左右:
2)线程锁:threading.Lock(),思考下为什么要上锁,不上锁我一样可以开启多线程
不上锁,使用多线程运行程序:
import threading
import time
n = 200000000
def work():
global n
for i in range(100000):
# 1.正常调用
n -= 1
if __name__ == '__main__':
# 两个线程共同操作n
start = time.time()
t1 = threading.Thread(target=work)
t2 = threading.Thread(target=work)
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print(n)
print(f"运行时间为:{end - start:.2f}秒")
print("程序运行结束")
运行结果,由结果可以看出来 最后的值是错乱的,如果不上锁 两个线程在处理大批量数据的时候会出现错乱的现象,这种现象是怎么产生的那?打个比方,t1(线程1),t2(线程2)
他们在执行任务的时候,t1执行完成一个任务后,由于耗时太少执行结果尚未同步给t2,此时正好分配到t1刚刚执行过的任务:
线程上锁:threading.Lock()
"""
锁得模块:threading.Lock()
注意:上锁与解锁 之间锁的代码越少越好
"""
import threading
import time
n = 200000000
# 锁
lock = threading.Lock()
# 检查锁是否是上下文管理器,如果是上下文管理器,可以简写调用方式。使用:with lock
print(hasattr(lock, '__enter__'))
print(hasattr(lock, '__exit__'))
def work():
global n
for i in range(100000):
# 1.正常调用
#n -= 1
#2.普通上锁
# #上锁
# lock.acquire()
# n -= 1
# #释放锁
# lock.release()
#3.使用上下文管理器编写
time.sleep(0.01)
with lock:
n -= 1
if __name__ == '__main__':
# 两个线程共同操作n
start = time.time()
t1 = threading.Thread(target=work)
t2 = threading.Thread(target=work)
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print(n)
print(f"运行时间为:{end - start:.2f}秒")
print("程序运行结束")
运行结果,上锁后避免了错领任务的事情,结果运行正常了。这里使用了with使代码看起来更优雅些,其实与现实2是一样的效果:
3)适用场景:上一章讲述了进程 这章节 讲述了 多线程,这时候有个疑问,什么时候使用多进程什么时候使用多进程那?他们到底有什么关联?
1.进程与线程:比如我们在使用博客这个软件,这时候系统会专门开一个进程运行博客,这个时候叫博客的进程,博客中有很多方法我们想同时执行浏览和写博客,保存或者修改操作 这个时候执行多个方法的操作叫做线程(这个例子也不是很好),同一个进程内,进程包含线程(这里需要注意,一个进程并不是能开多个线程程序耗时就一定会很快,能开多少线程取决于系统给这个进程分了多少资源)。
2.什么时候使用多进程:充分使用cpu的时候(单个进程cpu已经消耗很多了,此时不适合开多线程)
3.什么时候使用多线程:不充分使用cpu的时候,IO请求多的时候(io:这里是指网络请求)
爱折腾的小测试