对 C++ 对象的并发远程过程调用
Posted
技术标签:
【中文标题】对 C++ 对象的并发远程过程调用【英文标题】:Concurrent Remote Procedure Calls to C++ Object 【发布时间】:2013-07-17 21:53:40 【问题描述】:我想要一个用 C++ 编写的类作为远程过程调用服务器。
我有一个要解析的大(超过 1 GB)文件,读取参数以实例化对象,然后将其存储在 std::map 中。我希望 RPC 服务器监听来自客户端的调用,获取从客户端传递的参数,在 map 中查找适当的值,进行计算,并将计算的值返回给客户端,我希望它服务并发请求——所以我想让多个线程监听。顺便说一句,地图填充后,它不会改变。请求只会从中读取。
我想用 Python 编写客户端。服务器可以只是一个HTTP服务器,监听POST请求,客户端可以使用urllib发送吗?
我是 C++ 新手,所以我不知道如何编写服务器。谁能给我举一些例子?
【问题讨论】:
为什么选择 C++?您可以简单地编写一个 python 服务器 (***.com/questions/14088294/…)。如果您的计算耗时或在 C++ 中,只需使用 ctypes 包装它 你不能在 Python 中做线程,只能做多处理——所以如果服务器在 Python 中,我就不能拥有我想要的线程映射。 @JohnPeterThompsonGarcés:首先,是的,您可以在 Python 中执行线程。如果您只需要并发请求,那么您就完成了。如果您需要并发 CPU-bound 请求,其中 CPU-bound 代码是您的 C++ 类,只需让您的包装器围绕对该类的调用释放 GIL。虽然我们这样做了,但在进程之间共享std::map
并不难。
进程之间的任何共享都不需要大量的消息传递吗?我想使用共享内存。你谈到释放 GIL。这听起来很复杂。
您可以跨线程共享地图,就像在 C++ 中一样。对于 GIL,我发现这很有帮助 (docs.python.org/release/1.5.2/api/threads.html) 特别是 - Py_BEGIN_ALLOW_THREADS ...执行一些阻塞 I/O 操作... Py_END_ALLOW_THREADS
【参考方案1】:
也许因素会影响选择。
一种解决方案是使用 fastcgi。
客户端向启用了 fastCGI 的 HTTP 服务器发送 HTTP 请求。 HTP 服务器通过 fastcgi 机制将请求发送到您的 RPC 服务器。 RPC 服务器处理并生成响应,并发送回 http 服务器。 http 服务器将响应发送回您的客户端。
【讨论】:
【参考方案2】:如果你必须用 C++ 编写服务器,而你不知道如何去做,那么你肯定想使用框架。
那里有很多选择,而 *** 不是就不同选择征求意见的好地方。但是举个例子,JsonRpc-Cpp
让你用大约 10 行代码实现一个 JSON-RPC(通过原始 TCP 或 HTTP)服务器,加上你想要公开的每个 RPC 的一行样板。比从头开始编写服务器要容易得多。
所以,这是一个示例服务器:
#include <cstdlib>
#include <jsonrpc.h>
class Service
public:
bool echo(const Json::Value &root, Json::Value &response)
response["jsonrpc"] = "2.0";
response["id"] = root["id"];
Json::Value result;
result["params"] = root["params"];
response["result"] = result;
return response;
int main(int argc, char *argv[])
int port = std::atoi(argv[1]); // add some error handling here...
Json::Rpc::TcpServer server("127.0.0.1", port);
Service service;
server.AddMethod(new Json::Rpc::RpcMethod<Service>(service,
&Service::echo, "echo");
server.Bind(); // add error handling again
server.Listen();
while(true) server.WaitMessage(1000);
但是,如果你用 Python 编写服务器,或者使用 WSGI Web 服务器并用 Python 编写服务,然后从 Python 调用 C++ 代码(无论是通过ctypes
,还是通过构建一个使用 Cython 或 SIP 之类的包装器)。
这是在 Python 中使用 bjsonrpc
的同一台服务器:
import bjsonrpc
class Service(bjsonrpc.handlers.BaseHandler):
def echo(self, *args):
return 'params': args
server = bjsonrpc.createserver(handler_factory = Service)
server.serve()
【讨论】:
以上是关于对 C++ 对象的并发远程过程调用的主要内容,如果未能解决你的问题,请参考以下文章
来自 Python | 的远程过程调用红宝石 | ... 到 C++