最近在寫一個(gè)小機(jī)器人的小項(xiàng)目薇搁,將比較耗時(shí)且繁瑣的任務(wù)交由機(jī)器人處理斋扰,解放出人力資源。
機(jī)器人功能已完成啃洋。但是使用由主系統(tǒng)推送信息传货,到機(jī)器人執(zhí)行完成,再返回主系統(tǒng)結(jié)果宏娄,這樣的單進(jìn)程模式问裕,顯然不合理,于是想到了利用python的多進(jìn)程模式孵坚。
多進(jìn)程
多進(jìn)程使用python內(nèi)置的multiprocessing
模塊粮宛,它提供了一個(gè)Process
類來代表一個(gè)進(jìn)程對(duì)象窥淆。創(chuàng)建子進(jìn)程時(shí),只需要傳入一個(gè)執(zhí)行函數(shù)和函數(shù)的參數(shù)巍杈,用start()
方法啟動(dòng)忧饭。主程序和子程序的數(shù)據(jù)通信呢?也很簡單筷畦,在主進(jìn)程中使用put()
方法將數(shù)據(jù)傳給子進(jìn)程词裤,在子進(jìn)程中用get()
接收數(shù)據(jù)即可。
from multiprocessing import Process,Queue
...
#創(chuàng)建并啟動(dòng)子進(jìn)程
q = Queue()
#主進(jìn)程寫入數(shù)據(jù)
q.put(data)
p = Process(target=sub_proc, args=('這是子進(jìn)程', q))
p.start()
...
#子進(jìn)程內(nèi)接收數(shù)據(jù)
a=q.get()
...
接口調(diào)用
接口開發(fā)使用了flask-restful
鳖宾,編寫了兩個(gè)接口:Robot
和Next
,分別注冊(cè)到/v1/subprocess
和/v1/next
吼砂。Robot
用于接收主程序消息,Next
用來返回機(jī)器人執(zhí)行結(jié)果攘滩。
完整代碼如下:
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)
#模擬比較耗時(shí)的機(jī)器人程序帅刊,作為子進(jìn)程,由主進(jìn)程調(diào)用
def sub_proc(name,q):
print('運(yùn)行子進(jìn)程:%s (%s)'%(name,os.getpid()))
a=q.get()
print(a)
sleep(4)
print('子進(jìn)程結(jié)束')
#子進(jìn)程中的結(jié)果漂问,返回給主程序
@app.route('/',methods=['POST'])
def next_step():
print('調(diào)用下一個(gè)接口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)
#定義子進(jìn)程并啟動(dòng)
def run_sub_process(data):
q = Queue()
q.put(data)
p = Process(target=sub_proc, args=('這是子進(jìn)程', q))
print('子進(jìn)程啟動(dòng)鸠项,余寥,屏鳍,')
# 啟動(dòng)子進(jìn)程
p.start()
next_step()
#機(jī)器人接口吊说,接收主系統(tǒng)推送的信息,信息無誤會(huì)立即啟動(dòng)機(jī)器人磷仰,并即時(shí)返回消息給主系統(tǒng)
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.接收接口袍嬉,在子進(jìn)程中調(diào)用: 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('調(diào)用接收服務(wù)成功:接收內(nèi)容是:%s' % data.decode())
return jsonify({'msg': 'Success'})
api.add_resource(Next, '/v1/next')
if __name__ == '__main__':
app.run(debug=True, port=8090)
測(cè)試
同時(shí)運(yùn)行 multiprocess.py和simple.py 。
在終端使用curl
調(diào)用/v1/subprocess 接口灶平,檢查調(diào)用情況伺通,會(huì)發(fā)現(xiàn)子程序調(diào)用成功,并成功返回結(jié)果逢享。
curl -d {'wer':'ds'} http://127.0.0.1:8080/v1/subprocess