智能制造的快速落地,必然涉及工业互联网平台、工业 AI+、区域工业互联网,这些领域必然包含物联网、云计算、AI、大数据、协同等技术。
从具体落地情况来看,智能制造企业中常用的数据采集与监控系统(SCADA)中,必然涉及到消息队列+多线程的底层处理技术。因此,本文简单介绍一下基于python语言,如何实现消息队列和多线程之间的交互。
首先,在编写代码之前,明确我们的目的:
- RabbitMQ发送指令到消息队列;
- python读取消息队列里的内容指令(需注意,这里每个指令都需要反馈计算结果);
- python根据消息队列指令,在进程池里触发多进程;
- python将每个进程计算结果返回到RabbitMQ消息队列中。
理清楚我们的目的之后,我们需要注意以下几点:
- 需要实例化两个RabbitMQ,一个用于接收MQ指令,另外一个用于返回计算结果到MQ消息队列中;
- 为了提高计算效率,这里采用了进程池的技术,意味着当进程池子进程被全部占用之后,其他计算任务需等待进程池里子进程结束侯才能发起计算。
from concurrent.futures.thread import ThreadPoolExecutor
import pika
import json
class MQSub:
def __init__(self, **args_in):
self.username = args_in["username"] # RabbitMQ用户名
self.password = args_in["password"] # RabbitMQ密码
self.host = args_in["host"] # RabbitMQ主机
self.port = args_in["port"] # RabbitMQ端口
self.cmd_queue = args_in["cmd_queue"] # RabbitMQ指令队列
self.feedback_queue = args_in["feedback_queue"] # RabbitMQ指令计算结果反馈队列
"""作为客户端"""
credentials = pika.PlainCredentials(self.username, self.password)
conn_mq = pika.BlockingConnection(
pika.ConnectionParameters(host=self.host, port=self.port, virtual_host="/", credentials=credentials))
self.channel = conn_mq.channel()
# 声明消息队列,如果不存在将创建;并设置成永久类型。
self.channel.queue_declare(self.feedback_queue, durable=True)
# 定义回调函数,当消息队列中有新的通知时调用callback函数
def user_defined_func(self):
print("此处是用户自定义的函数")
# 接下来对计算的结果,反馈到MQ消息队列中
self.channel.basic_publish(exchange='', routing_key=self.feedback_queue, body=json.dumps(您想反馈的结果), properties=pika.BasicProperties(delivery_mode=2))
class MQ(MQSub):
def __init__(self, **args_in):
MQSub.__init__(**args_in)
def mq_exec(self):
"""作为消费端"""
credentials = pika.PlainCredentials(self.username, self.password)
conn_mq = pika.BlockingConnection(pika.ConnectionParameters(host=self.host, port=self.port, virtual_host="/", credentials=credentials))
channel = conn_mq.channel()
# 声明消息队列,如果不存在将创建;并设置成永久类型。
channel.queue_declare(self.cmd_queue, durable=True)
# 定义回调函数,当消息队列中有新的通知时调用callback函数
channel.basic_consume(self.cmd_queue, on_message_callback=self.callback)
channel.start_consuming()
channel.close()
def callback(self):
"""回调函数:在新消息来的时候执行"""
executor.submit(self.user_defined_func) # 将任务提交到进程池里执行,user_defined_func是用户定义的函数,args_in入参
if __name__ == "__main__":
executor = ThreadPoolExecutor(max_workers=10) # 开启线程池,并且定义线程池里线程总数为10个
后面实例化的部分,大家可根据具体问题再定义,我这里就不做过多的阐述。