最近在写一个小机器人的小项目,将比较耗时且繁琐的任务交由机器人处理,解放出人力资源。
机器人功能已完成。但是使用由主系统推送信息,到机器人执行完成,再返回主系统结果,这样的单进程模式,显然不合理,于是想到了利用python的多进程模式。
多进程
多进程使用python内置的multiprocessing
模块,它提供了一个Process
类来代表一个进程对象。创建子进程时,只需要传入一个执行函数和函数的参数,用start()
方法启动。主程序和子程序的数据通信呢?也很简单,在主进程中使用put()
方法将数据传给子进程,在子进程中用get()
接收数据即可。
from multiprocessing import Process,Queue
...
#创建并启动子进程
q = Queue()
#主进程写入数据
q.put(data)
p = Process(target=sub_proc, args=('这是子进程', q))
p.start()
...
#子进程内接收数据
a=q.get()
...
接口调用
接口开发使用了flask-restful
,编写了两个接口:Robot
和Next
,分别注册到/v1/subprocess
和/v1/next
。Robot
用于接收主程序消息,Next
用来返回机器人执行结果。
完整代码如下:
1.multiprocess.py
# coding:utf-8
# Created by Allen Zhang
# Date: 2017/7/15
import json
from multiprocessing import Process,Queue
import os
from time import sleep
from flask_restful import Api,Resource
from flask import Flask, request
import requests
app = Flask(__name__)
api = Api(app)
#模拟比较耗时的机器人程序,作为子进程,由主进程调用
def sub_proc(name,q):
print('运行子进程:%s (%s)'%(name,os.getpid()))
a=q.get()
print(a)
sleep(4)
print('子进程结束')
#子进程中的结果,返回给主程序
@app.route('/',methods=['POST'])
def next_step():
print('调用下一个接口next')
head = {"Content-Type":"application/json"}
url ='http://127.0.0.1:8090/v1/next'
data = json.dumps({'hi':'This is post from another api'})
resp = requests.post(url,data=data,headers=head)
print(resp.text)
#定义子进程并启动
def run_sub_process(data):
q = Queue()
q.put(data)
p = Process(target=sub_proc, args=('这是子进程', q))
print('子进程启动,,,')
# 启动子进程
p.start()
next_step()
#机器人接口,接收主系统推送的信息,信息无误会立即启动机器人,并即时返回消息给主系统
class Robot(Resource):
def post(self):
data = request.get_data().decode()
if data:
run_sub_process(data)
return 'Run sub process and ok'
else:
return 'Falied'
api.add_resource(Robot,'/v1/subprocess')
if __name__ == '__main__':
app.run(debug=True,port=8080)
2.接收接口,在子进程中调用: simple.py
# coding:utf-8
# Created by Allen Zhang
# Date: 2017/7/15
from flask_restful import Api, Resource
from flask import Flask, request, jsonify
app = Flask(__name__)
api = Api(app)
class Next(Resource):
def post(self):
data = request.get_data()
# print(data)
print('调用接收服务成功:接收内容是:%s' % data.decode())
return jsonify({'msg': 'Success'})
api.add_resource(Next, '/v1/next')
if __name__ == '__main__':
app.run(debug=True, port=8090)
测试
同时运行 multiprocess.py和simple.py 。
在终端使用curl
调用/v1/subprocess 接口,检查调用情况,会发现子程序调用成功,并成功返回结果。
curl -d {'wer':'ds'} http://127.0.0.1:8080/v1/subprocess
网友评论