Важно:
Этот код требует 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, для построения многопоточного сервера.