Параллельные удаленные вызовы процедур для объекта C++

Я хотел бы иметь класс, написанный на C++, который действует как удаленный сервер вызова процедур.

У меня есть большой (более гигабайта) файл, который я анализирую, читая параметры для создания экземпляров объектов, которые затем сохраняю в std::map. Я хотел бы, чтобы сервер RPC прослушивал вызовы от клиента, принимал параметры, переданные от клиента, искал соответствующее значение на карте, выполнял расчет и возвращал вычисленное значение обратно клиенту, и я хочу, чтобы он обслуживать одновременные запросы, поэтому я хотел бы прослушивать несколько потоков. Кстати, после заполнения карты она не меняется. Запросы будут только читать из него.

Я хотел бы написать клиент на Python. Может ли сервер быть просто HTTP-сервером, который прослушивает POST-запросы, а клиент может использовать urllib для их отправки?

Я новичок в C++, поэтому не знаю, как написать сервер. Может ли кто-нибудь указать мне на несколько примеров?


person John Thompson    schedule 17.07.2013    source источник
comment
Почему С++? Вы можете просто написать сервер python (stackoverflow.com/questions /14088294/). Если ваши расчеты требуют много времени или написаны на C++, просто оберните их с помощью ctypes.   -  person user1827356    schedule 18.07.2013
comment
Вы не можете создавать потоки в Python, только многопроцессорность, поэтому у меня не может быть многопоточной карты, которую я хочу иметь, если сервер на Python.   -  person John Thompson    schedule 18.07.2013
comment
@JohnPeterThompsonGarcés: Во-первых, да, вы можете создавать потоки в Python. Если вам просто нужны одновременные запросы, все готово. Если вам нужны одновременные запросы, привязанные к ЦП, где код, привязанный к ЦП, является вашим классом C++, просто заставьте свою оболочку освободить GIL вокруг вызовов в этот класс. И пока мы это делаем, не так уж сложно разделить std::map между процессами.   -  person abarnert    schedule 18.07.2013
comment
Разве любое совместное использование между процессами не потребует передачи большого количества сообщений? Я хочу использовать общую память. Вы говорите о выпуске GIL. Звучит сложно.   -  person John Thompson    schedule 18.07.2013
comment
Вы можете поделиться картой между потоками, как в C++. Для GIL я нашел это полезным (docs.python.org/ release/1.5.2/api/threads.html) В частности - Py_BEGIN_ALLOW_THREADS ...Выполнить блокировку операций ввода-вывода... Py_END_ALLOW_THREADS   -  person user1827356    schedule 18.07.2013


Ответы (2)


Возможно, факторы могут повлиять на выбор.

Одним из решений является использование fastcgi.

Клиент отправляет HTTP-запрос на HTTP-сервер с включенным fastCGI. HTP-сервер отправляет запрос на ваш RPC-сервер через механизм fastcgi. Сервер RPC обрабатывает и генерирует ответ и отправляет обратно на http-сервер. http-сервер отправляет ответ обратно вашему клиенту.

person ROTOGG    schedule 17.07.2013

Если вам нужно написать сервер на C++, и вы понятия не имеете, как это сделать, вы определенно захотите использовать фреймворк.

Есть много вариантов, и StackOverflow — не лучшее место, чтобы узнать мнение о различных вариантах. Но чтобы дать вам один пример, JsonRpc-Cpp позволяет реализовать JSON -RPC (через необработанный TCP или HTTP) примерно в 10 строках кода, плюс строка шаблона для каждого 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 и напишете службу на Python, а затем вызовете код C++ из Python (либо через 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()
person abarnert    schedule 17.07.2013