环境
Ubuntu 14.04 + gcc/g++4.8.4 +Python 2.7
需求
最近在搞一个项目,需要让C++和Python交互,当然这种交互不是在C++中调用Python代码,而是先让C++代码处理一个程序,再把输出用Python代码处理。
网上看到有人用socket解决,可本人对socket一向排斥,然后就采用了更强大的分布式RPC框架——ZeroMQ来让二者交互。
ZeroMQ介绍
ZeroMQ本质是一个消息队列服务,它类似于socket,和socket的区别是:普通的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系,人们对BSD套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而ZMQ屏蔽了这些细节,让你的网络编程更为简单。ZMQ用于node与node间的通信,node可以是主机或者是进程。
ZeroMQ被称为史上最快消息队列,它处于会话层之上,应用层之下,使用后台异步线程完成消息的接受和发送,完美的封装了Socket API,大大简化了编程人员的复杂度,被称为史上最强大的消息中间件。ZMQ是用C语言编写的,30us内完成消息的传输,能够兼容多个平台,多种语言,可以使用多种方式实现N对N的Socket连接。
优势
ZeroMQ作为一个更为高效的传输层,具有如下优势:
1.程序接口库是一个并发框架
2. 在集群和超级计算机上表现得比TCP更快
3. 通过inproc, IPC, TCP, 和 multicast进行传播消息
4. 通过发散,订阅,流水线,请求的方式连接
5. 对于不定规模的多核消息传输应用使用异步IO
6. 有非常大并且活跃的开源社区
7. 支持30+的语言
C++和Python交互代码
关于ZeroMQ在Ubuntu C++和Python的安装,我就不赘述了,网上有多得翻不过来的教程。我来示范下C++作为服务端和Python作为客户端的交互代码:
C++服务端代码如下:
//server.cpp
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <unistd.h>
int main () {
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:5555");
while (true) {
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
std::cout << "Received Hello" << std::endl;
// Do some 'work'
sleep (1);
// Send reply back to client
zmq::message_t reply (5);
memcpy ((void *) reply.data (), "World", 5);
socket.send (reply);
}
return 0;
}
编译命令:
g++ -g -Wall server.cpp -o server -lstdc++ -lzmq
也可以是更简单的:
g++ server.cpp -o server -lzmq
然后
./server
让服务端开启监听
Python客户端代码如下:
#client.py
#coding=utf-8
import zmq
context = zmq.Context()
print 'connect to hello world server'
socket = context.socket(zmq.REQ)
socket.connect('tcp://localhost:5555')
for request in range(1,10):
print 'send ',request,'...'
socket.send('hello')
message = socket.recv()
print 'received reply ',request,'[',message,']'
这里另开一个新的终端,直接
python client.py
就可以看到交互了。