`
peizhiinfo
  • 浏览: 1425083 次
文章分类
社区版块
存档分类
最新评论

gSoap的多线程程序

 
阅读更多

原文出处在这里

一 gSOAP需要的头文件:

//gsoap ns service name:calc
//gsoap ns service style:rpc
//gsoap ns service encoding:encoded
//gsoap ns service namespace:
http://127.0.0.1:8089/calc.wsdl
//gsoap ns service location:http://127.0.0.1:8089/cal
//gsoap ns schema namespace: urn:calc
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);
int ns__pow(double a, double b, double *result);

二 多线程服务器关键代码

#include
#include "calc.nsmap"
#include "soapH.h"

/////////////////////////////////////////////////////////////////////////
///宏与全局变量的定义
#define BACKLOG (100)
#define MAX_THR (10)
#define MAX_QUEUE (1000)


pthread_mutex_t queue_cs; //队列锁
pthread_cond_t queue_cv; //条件变量
SOAP_SOCKET queue[MAX_QUEUE]; //数组队列
int head =0, tail =0; //队列头队列尾初始化
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
void * process_queue(void *); //线程入口函数
int enqueue(SOAP_SOCKET); //入队列函数
SOAP_SOCKET dequeue(void); //出队列函数

//////////////////////////////////////////////////////////////////////////
//线程入口函数
void * process_queue(void * soap)
{
struct soap * tsoap = (struct soap *)soap;
for(;;)
{
tsoap->socket = dequeue();
if (!soap_valid_socket(tsoap->socket))
{
break;
}
soap_serve(tsoap);
soap_destroy(tsoap);
soap_end(tsoap);
}
return NULL;
}

//入队列操作
int enqueue(SOAP_SOCKET sock)
{
int status = SOAP_OK;
int next;
pthread_mutex_lock(&queue_cs);
next = tail +1;
if (next >= MAX_QUEUE)
next = 0;
if (next == head)
status = SOAP_EOM;
else
{
queue[tail] =sock;
tail = next;
}
pthread_cond_signal(&queue_cv);
pthread_mutex_unlock(&queue_cs);
return status;
}

//出队列操作
SOAP_SOCKET dequeue()
{
SOAP_SOCKET sock;
pthread_mutex_lock(&queue_cs);
while (head == tail )
{
pthread_cond_wait(&queue_cv,&queue_cs);
}
sock = queue[head++];
if (head >= MAX_QUEUE)
{
head =0;
}
pthread_mutex_unlock(&queue_cs);
return sock;
}


//////////////////////////具体服务方法////////////////////////////////////////
//加法的实现
int ns__add(struct soap *soap, double a, double b, double *result)
{
*result = a + b;
return SOAP_OK;
}
//减法的实现
int ns__sub(struct soap *soap, double a, double b, double *result)
{
*result = a - b;
return SOAP_OK;
}
//乘法的实现
int ns__mul(struct soap *soap, double a, double b, double *result)
{
*result = a * b;
return SOAP_OK;
}
//除法的实现
int ns__div(struct soap *soap, double a, double b, double *result)
{
if (b)
*result = a / b;
else
{
char *s = (char*)soap_malloc(soap, 1024);
sprintf(s, "Can't">http://tempuri.org/">Can't divide %f by %f", a, b);
return soap_sender_fault(soap, "Division by zero", s);
}
return SOAP_OK;
}
//乘方的实现
int ns__pow(struct soap *soap, double a, double b, double *result)
{
*result = pow(a, b);
if (soap_errno == EDOM) /* soap_errno 和errorno类似, 但是和widnows兼容 */
{
char *s = (char*)soap_malloc(soap, 1024);
sprintf(s, "Can't take the power of %f to %f", a, b);
sprintf(s, "Can't">http://tempuri.org/">Can't take power of %f to %f", a, b);
return soap_sender_fault(soap, "Power function domain error", s);
}
return SOAP_OK;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
//主函数
int main(int argc,char ** argv)
{
struct soap ServerSoap;
//初始话运行时环境
soap_init(&ServerSoap);
//如果没有参数,当作CGI程序处理
if (argc <2)
{
//CGI 风格服务请求,单线程
soap_serve(&ServerSoap);
//清除序列化的类的实例
soap_destroy(&ServerSoap);
//清除序列化的数据
soap_end(&ServerSoap);
}else
{
struct soap * soap_thr[MAX_THR];
pthread_t tid[MAX_THR];
int i,port = atoi(argv[1]);
SOAP_SOCKET m,s;
//锁和条件变量初始化
pthread_mutex_init(&queue_cs,NULL);
pthread_cond_init(&queue_cv,NULL);
//绑定服务端口
m = soap_bind(&ServerSoap,NULL,port,BACKLOG);
//循环直至服务套接字合法
while (!soap_valid_socket(m))
{
fprintf(stderr,"Bind port error! ");
m = soap_bind(&ServerSoap,NULL,port,BACKLOG);
}
fprintf(stderr,"socket connection successful %d ",m);

//生成服务线程
for(i = 0; i <MAX_THR; i++)

{
soap_thr[i] = soap_copy(&ServerSoap);
fprintf(stderr,"Starting thread %d ",i);
pthread_create(&tid[i],NULL,(void*(*)(void*))process_queue,(void*)soap_thr[i]);
}

for(;;)
{
//接受客户端的连接
s = soap_accept(&ServerSoap);
if (!soap_valid_socket(s))
{
if (ServerSoap.errnum)
{
soap_print_fault(&ServerSoap,stderr);
continue;
}else
{
fprintf(stderr,"Server timed out ");
break;
}
}
//客户端的IP地址
fprintf(stderr,"Accepted connection from IP= %d.%d.%d.%d socket = %d ",
((ServerSoap.ip)>>24)&&0xFF,((ServerSoap.ip)>>16)&0xFF,((ServerSoap.ip)>>8)&0xFF,(ServerSoap.ip)&0xFF,(ServerSoap.socket));
//请求的套接字进入队列,如果队列已满则循环等待
while(enqueue(s) == SOAP_EOM)
Sleep(1000);
}
//服务结束后的清理工作
for(i = 0; i < MAX_THR; i++)
{
while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
{
Sleep(1000);
}
}
for(i=0; i< MAX_THR; i++)
{
fprintf(stderr,"Waiting for thread %d to terminate ..",i);
pthread_join(tid[i],NULL);
fprintf(stderr,"terminated ");
soap_done(soap_thr[i]);
free(soap_thr[i]);
}
pthread_mutex_destroy(&queue_cs);
pthread_cond_destroy(&queue_cv);
}
//分离运行时的环境
soap_done(&ServerSoap);
return 0;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics