import socket
from multiprocessing import Process
defget_server():
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
return server
defget_talk(sock):
whileTrue:
data = sock.recv(1024)
print(data.decode('utf8'))
sock.send(data.upper())
if __name__ == '__main__':
server = get_server()
whileTrue:
sock, addr = server.accept()
p = Process(target=get_talk, args=(sock,))
互斥锁代码实操
锁:建议只加载操作数据的部分 否则整个程序的效率会极低
from multiprocessing import Process, Lock
import time
import json
import random
defsearch(name):
withopen(r'data.json', 'r', encoding='utf8') as f:
data = json.load(f)
print('%s查看票 目前剩余:%s' % (name, data.get('ticket_num')))
defbuy(name):
# 先查询票数withopen(r'data.json', 'r', encoding='utf8') as f:
data = json.load(f)
# 模拟网络延迟
time.sleep(random.randint(1, 3))
# 买票if data.get('ticket_num') > 0:
withopen(r'data.json', 'w', encoding='utf8') as f:
data['ticket_num'] -= 1
json.dump(data, f)
print('%s 买票成功' % name)
else:
print('%s 买票失败 非常可怜 没车回去了!!!' % name)
defrun(name, mutex):
search(name)
mutex.acquire() # 抢锁
buy(name)
mutex.release() # 释放锁if __name__ == '__main__':
mutex = Lock() # 产生一把锁for i inrange(10):
p = Process(target=run, args=('用户%s号' % i, mutex))
p.start()
"""
锁有很多种 但是作用都一样
行锁 表锁 ...
"""
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=('用户%s'%i,))# p.start()# p_list.append(p)# for p in p_list:# p.join()# print(time.time() - start_time)
t_list = []
for i inrange(100):
t = Thread(target=task, args=('用户%s'%i,))
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(time.time() - start_time)
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('主线程')
# 官方文档对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)
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)
python多线程是否有用
需要分情况
情况1
单个CPU
多个CPU
情况2需要分情况
情况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()) # 12 查看当前计算机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
"""
IO密集型(代码有IO操作)
计算密集型(代码没有IO)
1.在python并发编程中信号量相当于多把互斥锁(公共厕所)
2.在有些知识中信号量意思是达到某个条件自动触发其他操作
from threading import Thread, Lock, Semaphore
import time
import random
sp = Semaphore(5) # 一次性产生五把锁classMyThread(Thread):
defrun(self):
sp.acquire()
print(self.name)
time.sleep(random.randint(1, 3))
sp.release()
for i inrange(20):
t = MyThread()
t.start()
event事件
from threading import Thread, Event
import time
event = Event() # 类似于造了一个红绿灯deflight():
print('红灯亮着的 所有人都不能动')
time.sleep(3)
print('绿灯亮了 油门踩到底 给我冲!!!')
event.set()
defcar(name):
print('%s正在等红灯' % name)
event.wait() # 如果有Event()的情况下 代码遇到了.wait()才会继续执行print('%s加油门 飙车了' % name)
t = Thread(target=light)
t.start()
for i inrange(20):
t = Thread(target=car, args=('熊猫PRO%s' % i,))
t.start()
进程池与线程池
进程和线程能否无限制的创建 不可以
因为硬件的发展赶不上软件 有物理极限 如果我们在编写代码的过程中无限制的创建进程或者线程可能会导致计算机崩溃
池
降低程序的执行效率 但是保证了计算机硬件的安全
进程池
提前创建好固定数量的进程供后续程序的调用 超出则等待
线程池
提前创建好固定数量的线程供后续程序的调用 超出则等待
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import os
import time
import random
from threading import current_thread
# 1.产生含有固定数量线程的线程池# pool = ThreadPoolExecutor(10)
pool = ProcessPoolExecutor(5)
deftask(n):
print('task is running')
# time.sleep(random.randint(1, 3))# print('task is over', n, current_thread().name)# print('task is over', os.getpid())return'我是task函数的返回值'deffunc(*args, **kwargs):
print('from func')
if __name__ == '__main__':
# 2.将任务提交给线程池即可for i inrange(20):
# res = pool.submit(task, 123) # 朝线程池提交任务# print(res.result()) # 不能直接获取# pool.submit(task, 123).add_done_callback(func)"""
线程的返回值需要用异步回调机制获取 不能直接接受返回值
如果直接接受返回值会变成同步 异步回调机制由另一个函数接收
"""
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现