代码创建进程
'''
创建进程的方式:
1.鼠标点击桌面一个应用图标
2.代码创建
创建进程的本质:在内存中申请一块内存空间用于运行相应的程序代码
'''
from multiprocessing import Process
import time
def index():
print('这里是index')
if __name__ == '__main__':
print('start')
p = Process(target=index)
p.start()
print('wait')
time.sleep(1)
print('end')
>>>start
>>>wait
>>>这里是index
>>>end
'''
强调:不同的操作系统创建进程的要求不一样
在windows中创建进程是以导入模块的方式进行 所以创建进程的代码必须写在__main__子代码中,否则会直接报错 因为在无限制创建进程
在linux和mac中创建进程是直接拷贝一份源代码然后执行,不需要写在__main__子代码中
'''
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, username):
self.username = username
super().__init__()
def run(self):
print('你好啊 小姐姐',self.username)
time.sleep(3)
print('get out!!!',self.username)
if __name__ == '__main__':
p = MyProcess('jason')
p.start()
print('主进程')
>>>主进程
>>>你好啊 小姐姐 jason
>>>get out!!! jason
进程实现并发
'''
将于客户端通信的代码封装成一个函数,之后每来一个客户端就创建一个进程专门做交互
'''
import socket
from multiprocessing import Process
def get_server():
server = socket.socket()
server.bind(('127.0.0.1',8888))
server.listen(5)
return server
def msg_rcv(sock):
msg = sock.recv(1024)
print(msg.decode('utf8'))
sock.send(b'hello')
if __name__ == '__main__':
server = get_server()
while True:
sock,addr = server.accept()
p = Process(target=msg_rcv,args=(sock,))
p.start()
import socket
while True:
client = socket.socket()
client.connect(('127.0.0.1',8888))
client.send(b'jason')
msg = client.recv(1024)
print(msg.decode('utf8'))
join方法
1.join方法的简单使用
2.如何真正理解等待的过程
from multiprocessing import Process
import time
def task(name, n):
print(f'{name} is running')
time.sleep(n)
print(f'{name} is over')
if __name__ == '__main__':
p1 = Process(target=task, args=('jason', 1))
p2 = Process(target=task, args=('tony', 2))
p3 = Process(target=task, args=('kevin', 3))
start_time = time.time()
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
end_time = time.time() - start_time
print('主进程', f'总耗时:{end_time}')
'''
需求:p.start()之后的代码等待子进程全部运行结束之后在打印
1.错误做法:
直接sleep
因为不知道子进程运行的时间
2.join方法
'''
进程间数据默认隔离
from multiprocessing import Process
money = 999
def task():
global money
money = 666
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print(money)
'''默认隔离 但是可以通过一些技术打破'''
进程对象属性和方法
'''
进程号查看:
windows: tasklist的结果集中能够查看
mac: ps -ef
'''
1.进程号代码查看方法
from multiprocessing import Process,current_process
curren_process().pid
'''获取进程号的用处之一就是可以通过代码的方式管理进程'''在windows中可以通过 taskkill关键字杀死进程
os.getpid()
os.getppid()
2.杀死子进程
terminate()
3.判断子进程是否存活
is_alive()
僵尸进程于孤儿进程
僵尸进程:
所有的子进程在运行结束之后都会变成僵尸进程(死了但没有死透)
还保留这pid和一些运行过程中的记录便于主进程查看(短时间保存),这些信息会被主进程回收(彻底死亡)
孤儿进程:
子进程会被操作系统自动接管
守护进程
'''
守护 即死活全部参考守护对象
对象死亡自身则立即死亡
'''
from multiprocessing import Process
import time
def a():
print('live')
time.sleep(0.5)
print("died")
if __name__ == '__main__':
p = Process(target=a)
p.daemon = True
p.start()
time.sleep(0.5)
print('死了')
>>>live
>>>死了
互斥锁
'''
情景:
节假日抢票,手机显示还有票,但是点击购买的时候却提示已经没有票了,之后刷新查询确实是没票了
原因:上午10:00打开软件查询票数 接受到的数据是系统发过来的10:00的数据
只要不进行刷新,那么页面显示的永远是10:00的信息
'''
代码模拟抢票
import json
from multiprocessing import Process
import time
def view_ticket_num():
with open('data.json', 'r', encoding='utf8') as f:
dic = json.load(f)
print(f'当前票数:{dic["ticket_num"]}')
return dic
def buy_ticket(i):
dic = view_ticket_num()
num = dic['ticket_num']
time.sleep(1)
if num > 0:
dic['ticket_num'] -= 1
with open('data.json', 'w', encoding='utf8') as f:
json.dump(dic, f)
print(f'用户{i},买票成功')
if __name__ == '__main__':
for i in range(1, 10):
p = Process(target=buy_ticket, args=(i,))
p.start()
'''
当多个进程操作同一份数据的时候会造成数据的错乱
这个时候就需要加锁处理(互斥锁)
即将并发并称串行 牺牲了效率但是保证了数据的安全
互斥锁不能随意使用 容易造成死锁现象
互斥锁只能在处理数据的部分枷锁不能什么地方都加 严重影响程序的效率
'''
查票可以一次性给多人看 但是买票环节必须排队>>>互斥锁
from multiprocessing import Process, Lock
mutex = Lock()
mutex.acquire()
mutex .release()
'''
锁相关的知识
行锁:只针对行数据加锁 同一时间只能有一个人操作
表锁:只针对表数据进行加锁 同一时间只能一个人操作
'''
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人