进程如何优化以提升工作效率?

2026-05-22 05:421阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2714个文字,预计阅读时间需要11分钟。

进程如何优化以提升工作效率?

目录+ 代码创建流程+ join方法+ 进程间数据默认隔离+ 进程对象属性和方法+ 僵尸进程与孤儿进程+ 守护进程+ 互斥锁+ 内容代码创建流程+ 创建进程的方式+ 鼠标双击桌面一个应用图标+ 代码创建

目录
  • 代码创建进程
  • join方法
  • 进程间数据默认隔离
  • 进程对象属性和方法
  • 僵尸进程与孤儿进程
  • 守护进程
  • 互斥锁
内容 代码创建进程 创建进程的方式
  1. 鼠标双击桌面一个应用图标
  2. 代码创建
创建进程的方式

在内存中申请一块内存空间用于运行相应的程序代码

代码创建进程的两种方式

第一种:函数

from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) # 创建一个进程对象 p.start() # 告诉操作系统创建一个新的进程 print('主进程') View Code

打印结果为:

主进程 zhou is running zhou is over View Code

第二种:面向对象

from multiprocessing import Process import time class MyProcess(Process): def __init__(self,username): self.username = username super().__init__() def run(self): print('hello',self.username) time.sleep(3) print('hi',self.username) if __name__ == '__main__': p = MyProcess('zhou') p.start() print('主进程') View Code

打印结果为:

主进程 hello zhou hi zhou View Code 进程实现并发

服务端:

import socket server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(5) while True: # 链接循环 sock,add = server.accept() while True: # 通信循环 data = sock.recv(1024) # 不考虑粘包问题 print(data.decode('utf8')) sock.send(data.upper()) # 客户端发一个消息就立马回复一个消息的大写 View Code

客户端:

import socket client = socket.socket() client.connect(('127.0.0.1',8080)) while True: client.send(b'hello') data = client.recv(1024) print(data.decode('utf8')) View Code

多个客户端同时运行只能运行一个,服务端只能与一个进行交互

方法:将服务客户端的代码封装成函数(通信代码),并创建进程

服务端:

import socket from multiprocessing import Process server = socket.socket() server.bind(('127.0.0.1',8989)) server.listen(5) def task(sock): while True: # 通信循环 data = sock.recv(1024) # 不考虑粘包问题 print(data.decode('utf8')) sock.send(data.upper()) # 客户端发一个消息就立马回复一个消息的大写 if __name__ == '__main__': while True: # 链接循环 sock,add = server.accept() p = Process(target=task,args=(sock,)) p.start() View Code join方法

from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.start() print('主进程') View Code

基于上述代码产生需求

需求:想让p.start()之后的代码,等待子进程全部运行结束之后再打印

这里就用到了join方法:

from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.start() p.join() # 等待子进程运行结束之后再往下执行 print('主进程') View Code

如果子进程的睡眠时间是 sleep(n),并且有三个进程:

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=('zhou', 1)) p2 = Process(target=task, args=('zhou', 2)) p3 = Process(target=task, args=('zhou', 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}') View Code

请问总耗时大概是几秒?

结果:

zhou is running chen is running jin is running zhou is over chen is over jin is over 主进程 总耗时:3.1336801052093506 View Code

把上述代码修改一下:

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=('zhou', 1)) p2 = Process(target=task, args=('chen', 2)) p3 = Process(target=task, args=('jin', 3)) start_time = time.time() p1.start() p1.join() p2.start() p2.join() p3.start() p3.join() end_time = time.time() - start_time print('主进程',f'总耗时:{end_time}') View Code

那这次又是多少秒呢?

结果:

zhou is running zhou is over chen is running chen is over jin is running jin is over 主进程 总耗时:6.378488302230835 View Code 进程间数据默认隔离

内存可以看成是有很多个小隔间组成的,彼此不干扰

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) View Code

打印结果是:999

而子进程的money是多少呢?

from multiprocessing import Process money = 999 def task(): global money # 局部修改全局不可变类型 money = 666 print('子进程',money) if __name__ == '__main__': p = Process(target=task) p.start() p.join() print(money) View Code

结果为:

子进程 666
999

进程对象属性和方法 查看进程号
  1. windows终端: tasklist 进程号:PID
  2. mac终端:ps -ef 进程号:PID
代码查看进程号

获取进程号的用处之一:通过代码的方式管理进程

  1. current_process函数

    from multiprocessing import Process,current_process print(current_process().pid) View Code

    这里会拿到一个进程号,加上time模块就可以在拿到进程号之前在终端查看到该进程号

  2. os 模块

    import os def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': print('主进程号:',os.getpid()) print('主主进程:',os.getppid()) p = Process(target=task) p.start() View Code

    os.getpid() 获取当前进程的进程号

os.getppid() 获取当前进程的父进程号

杀死进程号
  1. 命令行:

    windows: taskkill关键字 ; mac/linux: kill关键字

  2. 代码: terminate()

    from multiprocessing import Process,current_process import os def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() print('主进程') View Code

    结果:主进程

判断子进程是否存活

is_alive()

import os def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() print(p.is_alive()) print('主进程') View Code

结果为:

True
主进程

布尔值为True的原因:terminate告诉操作系统杀死子进程需要一点时间

import os import time def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() time.sleep(0.1) print(p.is_alive()) print('主进程') View Code

结果为:

False
主进程

僵尸进程与孤儿进程 僵尸进程

所有的子进程在运行结束之后都会变成僵尸进程(死了但是没有死透)

还保留着pid和一些运行过程的中的记录便于主进程查看(短时间保存)

这些信息会被主进程回收(僵尸彻底死了)

孤儿进程

子进程存活者,父进程意外死亡

子进程会被操作系统自动接管

守护进程

守护:死活全部参考守护的对象,对象死立刻死

from multiprocessing import Process import time def task(name): print(f'{name}还活着') time.sleep(3) print(f'{name}死了') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.daemon = True # 将子进程设置为守护进程:主进程结束,子进程立刻结束 p.start() print('chen') View Code

结果为:chen

如果给主进程加一秒

from multiprocessing import Process import time def task(name): print(f'{name}还活着') time.sleep(3) print(f'{name}死了') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.daemon = True # 将子进程设置为守护进程:主进程结束,子进程立刻结束 p.start() time.sleep(1) print('chen') View Code

结果为:

zhou还活着
chen

使用场景:只要自己结束了,守护的程序也直接结束,不继续占用资源了

模拟抢票程序

import json from multiprocessing import Process import time import random # 查票 def check(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) print(f'{name}查询当前余票:%s'%data.get('ticket_num')) # 买票 def buy(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) time.sleep(random.randint(1,3)) # 判断是否还有余票 if data.get('ticket_num') > 0: data['ticket_num'] -= 1 with open(r'ticket_data.json','w',encoding='utf8') as f: json.dump(data,f) print(f'{name}抢票成功') else: print(f'{name}抢票失败,没有余票了') def run(name): check(name) buy(name) if __name__ == '__main__': for i in range(10): p = Process(target=run,args=('用户:%s'%i,)) p.start() View Code

结果为:

用户:0查询当前余票:4 用户:1查询当前余票:4 用户:2查询当前余票:4 用户:3查询当前余票:4 用户:4查询当前余票:4 用户:5查询当前余票:4 用户:6查询当前余票:4 用户:8查询当前余票:4 用户:7查询当前余票:4 用户:9查询当前余票:4 用户:8抢票成功 用户:1抢票成功 用户:2抢票成功 用户:3抢票成功 用户:4抢票成功 用户:7抢票成功 用户:0抢票成功 用户:6抢票成功用户:5抢票成功 用户:9抢票成功 View Code 互斥锁

刚才的抢票程序可以看出:当多个进程操作同一份数据的时候会造成数据的错乱

这个时候需要加锁处理(互斥锁)

将并发变成串行,虽然牺牲了效率但是保证了数据的安全

互斥锁在主进程中使用

进程如何优化以提升工作效率?

互斥锁不能轻易使用,容易造成死锁现象

互斥锁只在处理数据的部分加锁,不能什么地方都加,严重影响程序的效率

正确的抢票程序:

import json from multiprocessing import Process,Lock import time import random # 查票 def check(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) print(f'{name}查询当前余票:%s'%data.get('ticket_num')) # 买票 def buy(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) time.sleep(random.randint(1,3)) # 判断是否还有余票 if data.get('ticket_num') > 0: data['ticket_num'] -= 1 with open(r'ticket_data.json','w',encoding='utf8') as f: json.dump(data,f) print(f'{name}抢票成功') else: print(f'{name}抢票失败,没有余票了') def run(name,mutex): check(name) # 只需要把买票环节变成串行即可 mutex.acquire() # 抢锁 buy(name) mutex.release() # 放锁 if __name__ == '__main__': mutex = Lock() for i in range(1,10): p = Process(target=run,args=('用户:%s'%i,mutex)) p.start() View Code

锁的相关知识:

行锁:针对行数据加锁,同一时间只能一个人操作

表锁:针对表数据加锁,同一时间只能一个人操作

锁的应用范围很广,但是核心都是为了保证数据的安全

本文共计2714个文字,预计阅读时间需要11分钟。

进程如何优化以提升工作效率?

目录+ 代码创建流程+ join方法+ 进程间数据默认隔离+ 进程对象属性和方法+ 僵尸进程与孤儿进程+ 守护进程+ 互斥锁+ 内容代码创建流程+ 创建进程的方式+ 鼠标双击桌面一个应用图标+ 代码创建

目录
  • 代码创建进程
  • join方法
  • 进程间数据默认隔离
  • 进程对象属性和方法
  • 僵尸进程与孤儿进程
  • 守护进程
  • 互斥锁
内容 代码创建进程 创建进程的方式
  1. 鼠标双击桌面一个应用图标
  2. 代码创建
创建进程的方式

在内存中申请一块内存空间用于运行相应的程序代码

代码创建进程的两种方式

第一种:函数

from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) # 创建一个进程对象 p.start() # 告诉操作系统创建一个新的进程 print('主进程') View Code

打印结果为:

主进程 zhou is running zhou is over View Code

第二种:面向对象

from multiprocessing import Process import time class MyProcess(Process): def __init__(self,username): self.username = username super().__init__() def run(self): print('hello',self.username) time.sleep(3) print('hi',self.username) if __name__ == '__main__': p = MyProcess('zhou') p.start() print('主进程') View Code

打印结果为:

主进程 hello zhou hi zhou View Code 进程实现并发

服务端:

import socket server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(5) while True: # 链接循环 sock,add = server.accept() while True: # 通信循环 data = sock.recv(1024) # 不考虑粘包问题 print(data.decode('utf8')) sock.send(data.upper()) # 客户端发一个消息就立马回复一个消息的大写 View Code

客户端:

import socket client = socket.socket() client.connect(('127.0.0.1',8080)) while True: client.send(b'hello') data = client.recv(1024) print(data.decode('utf8')) View Code

多个客户端同时运行只能运行一个,服务端只能与一个进行交互

方法:将服务客户端的代码封装成函数(通信代码),并创建进程

服务端:

import socket from multiprocessing import Process server = socket.socket() server.bind(('127.0.0.1',8989)) server.listen(5) def task(sock): while True: # 通信循环 data = sock.recv(1024) # 不考虑粘包问题 print(data.decode('utf8')) sock.send(data.upper()) # 客户端发一个消息就立马回复一个消息的大写 if __name__ == '__main__': while True: # 链接循环 sock,add = server.accept() p = Process(target=task,args=(sock,)) p.start() View Code join方法

from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.start() print('主进程') View Code

基于上述代码产生需求

需求:想让p.start()之后的代码,等待子进程全部运行结束之后再打印

这里就用到了join方法:

from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.start() p.join() # 等待子进程运行结束之后再往下执行 print('主进程') View Code

如果子进程的睡眠时间是 sleep(n),并且有三个进程:

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=('zhou', 1)) p2 = Process(target=task, args=('zhou', 2)) p3 = Process(target=task, args=('zhou', 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}') View Code

请问总耗时大概是几秒?

结果:

zhou is running chen is running jin is running zhou is over chen is over jin is over 主进程 总耗时:3.1336801052093506 View Code

把上述代码修改一下:

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=('zhou', 1)) p2 = Process(target=task, args=('chen', 2)) p3 = Process(target=task, args=('jin', 3)) start_time = time.time() p1.start() p1.join() p2.start() p2.join() p3.start() p3.join() end_time = time.time() - start_time print('主进程',f'总耗时:{end_time}') View Code

那这次又是多少秒呢?

结果:

zhou is running zhou is over chen is running chen is over jin is running jin is over 主进程 总耗时:6.378488302230835 View Code 进程间数据默认隔离

内存可以看成是有很多个小隔间组成的,彼此不干扰

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) View Code

打印结果是:999

而子进程的money是多少呢?

from multiprocessing import Process money = 999 def task(): global money # 局部修改全局不可变类型 money = 666 print('子进程',money) if __name__ == '__main__': p = Process(target=task) p.start() p.join() print(money) View Code

结果为:

子进程 666
999

进程对象属性和方法 查看进程号
  1. windows终端: tasklist 进程号:PID
  2. mac终端:ps -ef 进程号:PID
代码查看进程号

获取进程号的用处之一:通过代码的方式管理进程

  1. current_process函数

    from multiprocessing import Process,current_process print(current_process().pid) View Code

    这里会拿到一个进程号,加上time模块就可以在拿到进程号之前在终端查看到该进程号

  2. os 模块

    import os def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': print('主进程号:',os.getpid()) print('主主进程:',os.getppid()) p = Process(target=task) p.start() View Code

    os.getpid() 获取当前进程的进程号

os.getppid() 获取当前进程的父进程号

杀死进程号
  1. 命令行:

    windows: taskkill关键字 ; mac/linux: kill关键字

  2. 代码: terminate()

    from multiprocessing import Process,current_process import os def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() print('主进程') View Code

    结果:主进程

判断子进程是否存活

is_alive()

import os def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() print(p.is_alive()) print('主进程') View Code

结果为:

True
主进程

布尔值为True的原因:terminate告诉操作系统杀死子进程需要一点时间

import os import time def task(): print('子进程号:',os.getpid()) print('父进程号:',os.getppid()) if __name__ == '__main__': p = Process(target=task) p.start() p.terminate() time.sleep(0.1) print(p.is_alive()) print('主进程') View Code

结果为:

False
主进程

僵尸进程与孤儿进程 僵尸进程

所有的子进程在运行结束之后都会变成僵尸进程(死了但是没有死透)

还保留着pid和一些运行过程的中的记录便于主进程查看(短时间保存)

这些信息会被主进程回收(僵尸彻底死了)

孤儿进程

子进程存活者,父进程意外死亡

子进程会被操作系统自动接管

守护进程

守护:死活全部参考守护的对象,对象死立刻死

from multiprocessing import Process import time def task(name): print(f'{name}还活着') time.sleep(3) print(f'{name}死了') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.daemon = True # 将子进程设置为守护进程:主进程结束,子进程立刻结束 p.start() print('chen') View Code

结果为:chen

如果给主进程加一秒

from multiprocessing import Process import time def task(name): print(f'{name}还活着') time.sleep(3) print(f'{name}死了') if __name__ == '__main__': p = Process(target=task,args=('zhou',)) p.daemon = True # 将子进程设置为守护进程:主进程结束,子进程立刻结束 p.start() time.sleep(1) print('chen') View Code

结果为:

zhou还活着
chen

使用场景:只要自己结束了,守护的程序也直接结束,不继续占用资源了

模拟抢票程序

import json from multiprocessing import Process import time import random # 查票 def check(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) print(f'{name}查询当前余票:%s'%data.get('ticket_num')) # 买票 def buy(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) time.sleep(random.randint(1,3)) # 判断是否还有余票 if data.get('ticket_num') > 0: data['ticket_num'] -= 1 with open(r'ticket_data.json','w',encoding='utf8') as f: json.dump(data,f) print(f'{name}抢票成功') else: print(f'{name}抢票失败,没有余票了') def run(name): check(name) buy(name) if __name__ == '__main__': for i in range(10): p = Process(target=run,args=('用户:%s'%i,)) p.start() View Code

结果为:

用户:0查询当前余票:4 用户:1查询当前余票:4 用户:2查询当前余票:4 用户:3查询当前余票:4 用户:4查询当前余票:4 用户:5查询当前余票:4 用户:6查询当前余票:4 用户:8查询当前余票:4 用户:7查询当前余票:4 用户:9查询当前余票:4 用户:8抢票成功 用户:1抢票成功 用户:2抢票成功 用户:3抢票成功 用户:4抢票成功 用户:7抢票成功 用户:0抢票成功 用户:6抢票成功用户:5抢票成功 用户:9抢票成功 View Code 互斥锁

刚才的抢票程序可以看出:当多个进程操作同一份数据的时候会造成数据的错乱

这个时候需要加锁处理(互斥锁)

将并发变成串行,虽然牺牲了效率但是保证了数据的安全

互斥锁在主进程中使用

进程如何优化以提升工作效率?

互斥锁不能轻易使用,容易造成死锁现象

互斥锁只在处理数据的部分加锁,不能什么地方都加,严重影响程序的效率

正确的抢票程序:

import json from multiprocessing import Process,Lock import time import random # 查票 def check(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) print(f'{name}查询当前余票:%s'%data.get('ticket_num')) # 买票 def buy(name): with open(r'ticket_data.json','r',encoding='utf8') as f: data = json.load(f) time.sleep(random.randint(1,3)) # 判断是否还有余票 if data.get('ticket_num') > 0: data['ticket_num'] -= 1 with open(r'ticket_data.json','w',encoding='utf8') as f: json.dump(data,f) print(f'{name}抢票成功') else: print(f'{name}抢票失败,没有余票了') def run(name,mutex): check(name) # 只需要把买票环节变成串行即可 mutex.acquire() # 抢锁 buy(name) mutex.release() # 放锁 if __name__ == '__main__': mutex = Lock() for i in range(1,10): p = Process(target=run,args=('用户:%s'%i,mutex)) p.start() View Code

锁的相关知识:

行锁:针对行数据加锁,同一时间只能一个人操作

表锁:针对表数据加锁,同一时间只能一个人操作

锁的应用范围很广,但是核心都是为了保证数据的安全