C++和Python 使用zmq的push和pull将任务下发给多个worker进程

zeroMQ在设计上的高性能特征

zeroMQ(ØMQ)是一个轻量级的消息传递库,为分布式应用提供高效的消息传递和线程间通信机制。它在设计上主要采用了以下几个高性能特征:

  1. 无锁的队列模型

    • 使用CAS(Compare-And-Swap)算法实现无锁队列,避免了多线程之间的锁竞争,提高了并发性能和响应速度。
    • 在数据交换通道(如用户端和session之间的数据交换)中,通过无锁队列模型实现异步事件的处理,提升了系统的响应能力和并发处理能力。
  2. 批量处理的算法

    • zeroMQ针对大量消息的处理进行了优化,支持批量发送和接收消息,减少了系统调用的开销,提升了消息处理效率和吞吐量。
  3. 多核下的线程绑定,无须CPU切换

    • 与传统的多线程并发模式不同,zeroMQ充分利用多核处理器的优势,将每个工作者线程绑定到单个CPU核心上运行,避免了多线程之间的CPU切换开销,提升了系统的性能和效率。
  4. 进程内通信和进程间通信

    • 使用zmq_inproc和zmq_ipc两种本地通信协议,分别适用于进程内和进程间的通信需求。
    • zmq_inproc通过共享内存实现进程内通信,无需使用额外的I/O线程,优化了通信的效率和资源利用率。
    • zmq_ipc利用系统相关的IPC(Inter-Process Communication)机制实现进程间的消息传递,保证了通信的可靠性和跨平台性。

zeroMQ C++发布任务进程

// Task ventilator in C++
// Binds PUSH socket to tcp://localhost:5557
// Sends batch of tasks to workers via that socket

#include <zmq.hpp>
#include <iostream>
#include <unistd.h>

int main() {
    zmq::context_t context(1);
    zmq::socket_t sender(context, ZMQ_PUSH);
    sender.bind("tcp://*:5557");

    std::cout << "Press Enter when the workers are ready: ";
    getchar();
    std::cout << "Sending tasks to workers...\n";

    int total_msec = 0;
    while (true) {
        int workload = /* generate workload */;
        total_msec += workload;

        zmq::message_t message(10);
        memcpy(message.data(), &workload, sizeof(int));
        sender.send(message);

        sleep(1); // Give 0MQ time to deliver
    }

    std::cout << "Total expected cost: " << total_msec << " msec\n";
    return 0;
}

Python接受任务、工作进程代码

import zmq

context = zmq.Context()
receiver = context.socket(zmq.PULL)
receiver.connect("tcp://localhost:5557")

while True:
    workload = receiver.recv_string()
    print(f"Received workload: {workload}")

Python发布任务进程

import zmq
import time

context = zmq.Context()
sender = context.socket(zmq.PUSH)
sender.bind("tcp://*:5557")

while True:
    workload = /* generate workload */
    sender.send_string(str(workload))
    time.sleep(1)  # Give 0MQ time to deliver

优缺点分析

优点:

  • 高性能:采用无锁队列和批量处理算法,优化了消息传递和处理效率。
  • 可扩展性:支持多核并发,利用多核处理器的优势,提升了系统的并发处理能力。
  • 灵活性:提供多种通信模式和协议选择,适应不同的通信场景和需求。
  • 跨平台性:支持多种操作系统,包括Windows、Linux等,具备良好的跨平台性和可移植性。

缺点:

  • 学习曲线较陡:zeroMQ的概念和API需要一定的学习成本,特别是对于初学者而言。
  • 复杂性:在复杂的网络拓扑和大规模系统中,需要合理设计和管理zeroMQ的消息传递机制,以避免潜在的性能和稳定性问题。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
zmqpush和pub通讯方式如下: 1. Push- Pull 模式 Push- Pull 模式是一种简单的分布式消息传递模式,其中一个进程将消息推送给另一个进程。在这种模式下,一方只能发出消息,而另一方只能接收消息。 示例代码: ``` # Push import zmq context = zmq.Context() socket = context.socket(zmq.PUSH) socket.bind("tcp://*:5555") # 发送消息 for i in range(5): message = "Message %s" % i socket.send(message.encode("utf-8")) # Pull import zmq context = zmq.Context() socket = context.socket(zmq.PULL) socket.connect("tcp://localhost:5555") # 接收消息 while True: message = socket.recv() print("Received message: %s" % message.decode("utf-8")) ``` 2. Pub- Sub 模式 Pub- Sub 模式是一种发布- 订阅模式,其中一个进程可以发布消息,而其他进程可以订阅并接收这些消息。在这种模式下,发布者(pub)不知道谁将接收消息,而订阅者(sub)也不知道消息来自哪里。 示例代码: ``` # Pub import zmq import time context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("tcp://*:5555") # 发送消息 for i in range(5): topic = "Topic %s" % (i % 3) message = "Message %s" % i socket.send_multipart([topic.encode("utf-8"), message.encode("utf-8")]) time.sleep(1) # Sub import zmq context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect("tcp://localhost:5555") # 订阅消息 socket.setsockopt(zmq.SUBSCRIBE, b"Topic 1") # 接收消息 while True: [topic, message] = socket.recv_multipart() print("Received message: %s, topic: %s" % (message.decode("utf-8"), topic.decode("utf-8"))) ``` 在以上代码中,订阅者只订阅了“Topic 1”的消息,所以只会收到这个主题的消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘色的喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值