многопоточность gSOAP - PullRequest
       28

многопоточность gSOAP

2 голосов
/ 16 ноября 2011

Я пытаюсь создать многопоточный веб-сервис.Однопоточность работает, в моей основной функции я использую это:

int main(int argc, char **argv) {
    CardSoapBindingService CardSrvc;
    Config Conf ;
    Conf.update();

    int port = Conf.listener_port;
    if (!port)
        CardSrvc.serve();
    else {
        if (CardSrvc.run(port)) {
            CardSrvc.soap_stream_fault(std::cerr);
            exit(-1);
        }
    }
    return 0;
}

Но я хочу многопоточность, поэтому я посмотрел в документации и нашел пример , который я попробовал вместо этого мой код,При компиляции я получаю следующие ошибки:

main.cpp: в функции int main(int, char**)': main.cpp:56: error: soap_serve 'undeclared (сначала используйте эту функцию)
main.cpp: 56: error: (Каждый необъявленный идентификатор сообщается только один раздля каждой функции она указана в.)
main.cpp: в функции void* process_request(void*)':<br> main.cpp:101: error: soap_serve 'undeclared (сначала используйте эту функцию)
make: *** [main.o] Fehler 1

Как я могу заставить это работать?

1 Ответ

8 голосов
/ 23 ноября 2011

Важно:

Этот код требует gsoap версии 2.8.5 как минимум. Первоначально он был построен на Solaris 8 с gsoap версии 2.8.3, портирование кода на Ubuntu и запуск под Valgrind показали, что библиотека 2.8.3 gsoap ++ повреждает память, что приводит к SIGSEGV. Следует отметить, что по состоянию на 25/11/11 версия gsoap, которую Ubuntu устанавливает с помощью apt-get, является неработающей 2.8.3. Требовалась загрузка и сборка последней версии gsoap вручную (обязательно установите flex и bison перед настройкой сборки gsoap!).

Используя gsoap 2.8.5, приведенный ниже код успешно создает потоки и передает SOAP-сообщения нескольким клиентам, теперь valgrind сообщает 0 ошибок с выделением памяти.


Глядя на ваш код, вы работаете с примером, созданным с опцией -i (или -j) для создания объектов C ++. Примеры потоков в dsomention gsoap написаны на стандартном C; отсюда ссылка на такие функции, как soap_serve (), которых у вас нет.

Ниже приведено мое быстрое переписывание многопоточного примера использования созданных объектов C +. Он основан на следующем файле определения:

// Content of file "calc.h": 
//gsoap ns service name: Calculator 
//gsoap ns service style: rpc 
//gsoap ns service encoding: encoded 
//gsoap ns service location: http://www.cs.fsu.edu/~engelen/calc.cgi 
//gsoap ns schema namespace: urn:calc 
//gsoap ns service method-action: add "" 
int ns__add(double a, double b, double &result); 
int ns__sub(double a, double b, double &result); 
int ns__mul(double a, double b, double &result); 
int ns__div(double a, double b, double &result);

Код основного сервера выглядит следующим образом:

#include "soapCalculatorService.h"  // get server object 
#include "Calculator.nsmap"     // get namespace bindings

#include <pthread.h>

void *process_request(void *calc) ;

int main(int argc, char* argv[]) 
{ 
    CalculatorService c;
    int port = atoi(argv[1]) ;
    printf("Starting to listen on port %d\n", port) ;
    if (soap_valid_socket(c.bind(NULL, port, 100)))
    {
        CalculatorService *tc ;
        pthread_t tid; 
        for (;;)
        {
            if (!soap_valid_socket(c.accept()))
                return c.error;
            tc = c.copy() ; // make a safe copy 
            if (tc == NULL) 
                break; 
            pthread_create(&tid, NULL, (void*(*)(void*))process_request, (void*)tc); 

            printf("Created a new thread %ld\n", tid) ;
        }
    }
    else {
        return c.error;
    }

} 


void *process_request(void *calc) 
{ 
   pthread_detach(pthread_self());
   CalculatorService *c = static_cast<CalculatorService*>(calc) ;
   c->serve() ;
   c->destroy() ;
   delete c ;
   return NULL; 
}  

Это очень базовая модель потоков, но она показывает, как использовать классы C ++, сгенерированные gsoap, для построения многопоточного сервера.

...