2011-11-16 3 views
2

iam이 멀티 스레딩 웹 서비스를 구축하려고합니다. 단일 스레드 내 주요 기능으로 작동하고 나는이 사용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 '는 미표시는 (제 1이 함수를 사용하여)
가 MAIN.CPP : 56 : 오차 (각 선언되지 않은 식별자 한번만 기능보고 나타나는 컴파일 동안이 에러를 얻을 에)
MAIN.CPP :. 기능 void* process_request(void*)':<br> main.cpp:101: error: soap_serve에서 '처음이 기능을) 사용 (신고되지 않은
메이크업 : *** [main.o를] ​​대해서는 2 1

어떻게 내가이 작업을 얻을 수 있나요? 중요

답변

7

는 :

이 코드는 최소한 버전 2.8.5을 gsoap이 필요합니다. 처음에는 Solaris 8에서 gsoap 버전 2.8.3을 사용하여 코드를 Ubuntu로 이식하고 valgrind에서 실행하면 2.8.3 gsoap ++ 라이브러리가 SIGSEGV로 이어지는 메모리를 손상시키는 것으로 나타났습니다. 25/11/11 현재 우분투가 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++ 예제를 더 많이 포함시키는 것이 좋다. –