from threading import Thread
from multiprocessing import Process
import time
deftask(name):
print(f'{name} is running')
time.sleep(0.1)
print(f'{name} is over')
if __name__ == '__main__':
start_time = time.time()
# p_list = []# for i in range(100):# p = Process(target=task, args=(f'用户{i}',))# p.start()# p_list.append(p)# for p in p_list:# p.join()# print(time.time() - start_time) # 0.7657256126403809# t_list = []# for i in range(100):# t = Thread(target=task, args=(f'用户{i}',))# t.start()# t_list.append(t)# for t in t_list:# t.join()# print(time.time() - start_time) # 0.1122446060180664# t = Thread(target=task, args=('jason',))# t.start()# print('主线程')"""
创建线程无需考虑反复执行的问题
"""classMyThread(Thread):
defrun(self):
print('run is running')
time.sleep(1)
print('run is over')
obj = MyThread()
obj.start()
print('主线程')
线程的诸多特性
1.join方法
from threading import Thread
import time
deftask(name):
print(f'{name} is running')
time.sleep(1)
print(f'{name} is over')
t = Thread(target=task, args=('程序', ))
t.start()
t.join()
print('主线程')
2.同进程内多个线程数据共享
3.current_thread()
4.active_count()
import time
from threading import Thread, current_thread, active_count
import os
money = 1000deftask():
time.sleep(3)
global money
money = 666print(current_thread().name)
print('子线程进程号>>>:', os.getpid())
for i inrange(10):
t = Thread(target=task)
t.start()
print(money)
print('存活的线程数', active_count())
print(current_thread().name)
print('主线程进程号>>>:', os.getpid())
GIL全局解释器锁
官方文档对GIL的解释
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management isnot thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.
"""
1.在CPython解释器中存在全局解释器锁简称GIL
python解释器有很多类型
CPython JPython PyPython(常用的是CPython解释器)
2.GIL本质也是一把互斥锁 用来阻止同一个进程内多个线程同时执行(重要)
3.GIL的存在是因为CPython解释器中内存管理不是线程安全的(垃圾回收机制)
垃圾回收机制
引用计数、标记清楚、分带回收
"""
验证GIL的存在
from threading import Thread
num = 100deftask():
global num
num -= 1
t_list = []
for i inrange(100):
t = Thread(target=task)
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(num) # 0
GIL与普通互斥锁
既然CPython解释器中有GIL 那么我们以后写代码是不是就不需要操作锁了!!!
"""
GIL只能够确保同进程内多线程数据不会被垃圾回收机制弄乱
并不能确保程序里面的数据是否安全
"""import time
from threading import Thread, Lock
num = 100deftask(mutex):
global num
mutex.acquire()
count = num
time.sleep(0.1)
num = count - 1
mutex.release()
mutex = Lock()
t_list = []
for i inrange(100):
t = Thread(target=task, args=(mutex,))
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(num) # 0
GIL锁是解释器级别的锁,保证同一时刻进程中只有一个线程拿到GIL锁,拥有执行权限。而线程互斥锁是保证同一时刻只有一个线程能对数据进行操作,是数据级别的锁
python多线程是否有用
需要分情况
情况1
单个CPU
多个CPU
情况2
IO密集型(代码有IO操作)
计算密集型(代码没有IO)
1.单个CPU
IO密集型
多进程
申请额外的空间 消耗更多的资源
多线程
消耗资源相对较少 通过多道技术
ps:多线程有优势!!!
计算密集型
多进程
申请额外的空间 消耗更多的资源(总耗时+申请空间+拷贝代码+切换)
多线程
消耗资源相对较少 通过多道技术(总耗时+切换)
ps:多线程有优势!!!
2.多个CPU
IO密集型
多进程
总耗时(单个进程的耗时+IO+申请空间+拷贝代码)
多线程
总耗时(单个进程的耗时+IO)
ps:多线程有优势!!!
计算密集型
多进程
总耗时(单个进程的耗时)
多线程
总耗时(多个进程的综合)
ps:多进程完胜!!!
from threading import Thread
from multiprocessing import Process
import os
import time
defwork():
# 计算密集型
res = 1for i inrange(1, 100000):
res *= i
if __name__ == '__main__':
print(os.cpu_count()) # 20 查看当前计算机CPU个数
start_time = time.time()
# p_list = []# for i in range(12): # 一次性创建12个进程# p = Process(target=work)# p.start()# p_list.append(p)# for p in p_list: # 确保所有的进程全部运行完毕# p.join()
t_list = []
for i inrange(12):
t = Thread(target=work)
t.start()
t_list.append(t)
for t in t_list:
t.join()
print('总耗时:%s' % (time.time() - start_time)) # 获取总的耗时"""
计算密集型
多进程:5.665567398071289
多线程:30.233906745910645
"""defwork():
time.sleep(2) # 模拟纯IO操作if __name__ == '__main__':
start_time = time.time()
# t_list = []# for i in range(100):# t = Thread(target=work)# t.start()# for t in t_list:# t.join()
p_list = []
for i inrange(100):
p = Process(target=work)
p.start()
for p in p_list:
p.join()
print('总耗时:%s' % (time.time() - start_time))
"""
IO密集型
多线程:0.0149583816528320
多进程:0.6402878761291504
"""
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!