2011-11-16 91 views
2

iam试图构建一个多线程web服务。单线程工作,在我的主要功能我用这个:gSOAP多线程

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; 
} 

但我想多线程的,所以我看的文档中,发现他们的example,我试过,而不是我的代码。虽然编译我得到这个错误:

main.cpp中:在功能int main(int, char**)': main.cpp:56: error: soap_serve”未申报(第一次使用此功能)
的main.cpp:56:错误:(每个未声明的标识符报道只有一次每个 功能出现在)
main.cpp中:在功能void* process_request(void*)':<br> main.cpp:101: error: soap_serve”未申报(第一次使用此功能)
化妆:*** [main.o] Fehler 1

我怎么能得到这个工作?

回答

7

重要:

此代码需要gSOAP的2.8.5版本最低。它最初建立在带有gsoap 2.8.3版本的Solaris 8上,将代码移植到Ubuntu并在valgrind下运行,表明2.8.3 gsoap ++库破坏了导致SIGSEGV的内存。应该指出的是,截至25/11/11,Ubuntu使用apt-get安装的gsoap的版本是2.8.3。需要手动下载并构建最新版本的gsoap(确保在配置gsoap构建之前安装flex和bison!)。

使用gsoap 2.8.5下面的代码愉快地创建线程并向多个客户端提供SOAP消息,valgrind现在报告0内存分配错误。


看你的代码的例子,你有工作已经建成使用-i(或-j)选项来创建C++对象。 gsoap doumention中的线程示例用标准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构建一个多线程服务器。

+0

+1感谢您的示例! gsoap文档并不像一些文档那么糟糕,但可以确保使用更新。罗伯特将很好地包含更多的C++例子,比如你的。 –