进程
定义:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位
查看当前进程,以及创建子进程
import os
print('当前正在运行的进程:%d' %os.getpid())
print('当前进程的父进程的%d' %os.getppid())
print('创建一个子进程......')
pid = os.fork()
print('创建的子进程的',pid) #fork函数的返回值有两个,产生的子进程返回的是一个0,父进程返回的时子进程的pid
if pid == 0:
print('这是创建的子进程,子进程的id为%d,父进程的id为%d' %(os.getpid(),os.getppid()))
else:
print('这是父进程%s的返回值%s' %(os.getpid(),pid))
结果:
multiprocessing创建进程
import multiprocessing
def job():
print('当前子进程的名称为%s' %(multiprocessing.current_process())) #current_process()获取当前进程的名字
#创建一个进程对象
p1 = multiprocessing.Process(target=job)
#运行多进程,执行任务
p1.start()
p2 = multiprocessing.Process(target=job)
p2.start()
#等待所有的子进程结束,子执行主进程的内容
p1.join() #阻塞
p2.join()
print('任务执行结束.......')
结果:
通过继承的方法创建子进程
import multiprocessing
#通过继承的方法与同过继承实现线程类似,只不过改了所继承的父类
class Jobprocess(multiprocessing.Process):
def __init__(self):
super(Jobprocess,self).__init__() #继承Process的构造方法
def run(self):
print('当前的子进程名称为%s' %(multiprocessing.current_process()))
processes = []
for i in range(10):
p = Jobprocess()
p.start()
processes.append(p)
[process.join() for process in processes]
print('任务执行结束')
结果:
多进程引用
import multiprocessing
import threading
from mytimeit import timeit
class Jobprocess(multiprocessing.Process):
def __init__(self,li): #获取新的方法
super(Jobprocess,self).__init__()
self.li = li
def run(self): #重写run方法将所要执行的函数放到里面
for item in self.li:
sum(item)
class Jobthread(threading.Thread):
def __init__(self,li):
super(Jobthread,self).__init__()
self.li = li
def run(self):
for item in self.li:
sum(item)
@timeit
def use_multi_process():
#1)开启的进程数取绝于cpu的个数
#2)如果处理的数据足够小,不建议使用多进程,因为创建进程和销毁进程需要时间,开启的进程数越多,反而越慢
#3)如果处理的数据量足够大,开启的进程数越多,效率越高
lists = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6],
[2, 3, 4, 5, 6, 7, 8], [2, 3, 4, 5, 6]] * 100000
processes = []
for i in range(0,len(lists),1000):
#对于处理i的数据进行分片,每个进程处理一部分任务
p = Jobprocess(lists[i:i+1000])
p.start()
processes.append(p)
[process.join() for process in processes]
print('多进程执行结束......')
@timeit
def use_multi_thread():
lists = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6],
[2, 3, 4, 5, 6, 7, 8], [2, 3, 4, 5, 6]] * 100000
threads = []
for i in range(0,len(lists),1000):
t= Jobthread(lists[i:i+1000])
t.start()
threads.append(t)
[thread.join() for thread in threads]
print('多线程执行结束......')
if __name__ == '__main__':
use_multi_process()
use_multi_thread()
结果:
进程的阻塞 终止 守护
阻塞:当子进程全部执行完毕之后再执行主进程。
终止:停止当前所有进程的操作
守护:当主进程执行完毕之后,将没有执行完的子进程全部杀死。
终止:
import time
import multiprocessing
def job():
print('start...')
time.sleep(3)
print('end...')
if __name__ == '__main__':
p = multiprocessing.Process(target=job)
print('Before:',p.is_alive()) #is_alive()查看当前进程的状态
p.start()
print('After:',p.is_alive())
p.terminate() #终止进程
print('terminate:',p.is_alive()) #此处之所以没有显示False的原因是进程被杀死需要时间
p.join()
print('joined:',p.is_alive())
结果:
守护:
import multiprocessing
import time
def job():
name = multiprocessing.current_process()
print('开始运行',name)
time.sleep(3)
print('结束进程...')
if __name__=="__main__":
p1 = multiprocessing.Process(target=job,name='use deamon')
p1.daemon = True #当主进程执行完之后,如果‘结束进程...’还没有打印,将不打印
p1.start()
p1.join(1)
print('程序执行结束')
结果:
进程池
使用进程池的原因:如果启动大量进程,会花费大量的时间出创建和销毁进程,使用进程池不需要启动和销毁大量进程。
import multiprocessing
import time
def job(id):
print('start %d' %(id))
print('end %d' %(id))
pool = multiprocessing.Pool(10) #创建一个进程池对象
for i in range(10):
pool.apply_async(job,args=(i, )) #向进程池里添加任务
pool.close()
pool.join()
print('success')
进程之间的通信
此列列举了生产者和消费者之间的通信,主要是通过队列在二者之间通信。
import multiprocessing
from multiprocessing import Queue
import time
class Producer(multiprocessing.Process):
#向队列里面添加内容
def __init__(self,queue):
super(Producer,self).__init__()
self.queue = queue
def run(self):
for i in range(10):
self.queue.put(i)
time.sleep(0.1)
print('传递的消息为,内容为:%s' %i)
class Consumer(multiprocessing.Process):
#读取队列里面的内容
def __init__(self,queue):
super(Consumer,self).__init__()
self.queue = queue
def run(self):
while True:
time.sleep(0.1)
print('读取的消息为:%s' %(self.queue.get()))
if __name__ == "__main__":
q = Queue() #创建一个队列对象
p1 = Producer(q)
p2 = Consumer(q)
p1.start()
p2.start()
结果:
分布式进程
管理端
import random
from queue import Queue
from multiprocessing.managers import BaseManager
#1.创建需要的队列
#task_queue存储的是任务需要传递的参数
task_queue = Queue()
#result_queue存储的是任务执行的结果
result_queue = Queue()
#将队列注册到网络上,以便其他主机进行访问,
BaseManager.register('get_task_queue',callable=lambda :task_queue)
BaseManager.register('get_result_queue',callable=lambda : result_queue)
#绑定端口为4000,暗号为westos
manager = BaseManager(address=('172.25.254.250',4000),authkey=b'westos')
#启动manager,开始共享队列
manager.start()
#通过网络访问共享的Queue对象
#manager.register:注册一个队列,唯一标识'get_task_queue'
#manager.get_task_queue()调用注册,调用的过程中的内容为callable指向的函数
task = manager.get_task_queue()
result = manager.get_result_queue()
#往队列里面放需要执行的数据
for i in range(100):
n = random.randint(1,100)
task.put(n)
print('任务列表加入任务:%d' %(n))
#从队列里面读取各个主机i执行的结果
for j in range(100):
res = result.get()
print('队列任务的执行结果:%s' %(res))
#关闭manager,取消共享序列
manager.shutdown()