声明:JavaEye新闻文章的版权属于JavaEye网站所有,严禁任何网站转载本文,否则必将追究法律责任!
SPProcPool 是一个 linux/unix 平台上的进程池服务器框架,使用 c++ 实现。
在 0.5 版中增加了一个类似 apache worker 的服务器模型。在之前 Leader/Follower 模型的基础上,在每个子进程中使用一个固定大小的线程池来为每个请求服务。这个模型的特点是能够支持较高的并发连接数。
项目主页:
http://code.google.com/p/spprocpool/
下载地址:
http://spprocpool.googlecode.com/files/spprocpool-0.5.src.tar.gz
SPProcPool 服务器框架的使用比较简单。下面以一个简单的服务器为例进行说明。
这个服务器是模仿《unix网络编程(第二版)》(中文版)第27章的服务器。服务器从 socket 读入包含一个数字的一行,然后根据这个数字返回相应的内容。
SPProcPool 提供的 SP_ProcMTServer 类就是在 0.5 版新增的服务器模型。这个类定义如下:
从接口中可以看到,要使用 SP_ProcMTServer ,需要提供一个 SP_ProcInetServiceFactory 类的实例。这个类相关的定义如下:
这里使用的是典型的抽象工厂方法。在工厂类中,除了 create 方法之外,还有两个特别的方法:workerInit 和 workerEnd 。workerInit 在子进程开始运行的时候被调用,workerEnd 在子进程退出的时候被调用。在 Service 类中,只有一个 handle 方法,它的参数就是已经 accept 到 socket 。
要实现这个简单的服务器例子,代码如下:
在 0.5 版中增加了一个类似 apache worker 的服务器模型。在之前 Leader/Follower 模型的基础上,在每个子进程中使用一个固定大小的线程池来为每个请求服务。这个模型的特点是能够支持较高的并发连接数。
项目主页:
http://code.google.com/p/spprocpool/
下载地址:
http://spprocpool.googlecode.com/files/spprocpool-0.5.src.tar.gz
SPProcPool 服务器框架的使用比较简单。下面以一个简单的服务器为例进行说明。
这个服务器是模仿《unix网络编程(第二版)》(中文版)第27章的服务器。服务器从 socket 读入包含一个数字的一行,然后根据这个数字返回相应的内容。
SPProcPool 提供的 SP_ProcMTServer 类就是在 0.5 版新增的服务器模型。这个类定义如下:
class SP_ProcMTServer {
public:
SP_ProcMTServer( const char * bindIP, int port,
SP_ProcInetServiceFactory * factory );
virtual ~SP_ProcMTServer();
virtual int start();
};
从接口中可以看到,要使用 SP_ProcMTServer ,需要提供一个 SP_ProcInetServiceFactory 类的实例。这个类相关的定义如下:
class SP_ProcInetService {
public:
virtual ~SP_ProcInetService();
virtual void handle( int socketFd ) = 0;
};
class SP_ProcInetServiceFactory {
public:
virtual ~SP_ProcInetServiceFactory();
virtual SP_ProcInetService * create() const = 0;
virtual void workerInit( const SP_ProcInfo * procInfo );
virtual void workerEnd( const SP_ProcInfo * procInfo );
};
这里使用的是典型的抽象工厂方法。在工厂类中,除了 create 方法之外,还有两个特别的方法:workerInit 和 workerEnd 。workerInit 在子进程开始运行的时候被调用,workerEnd 在子进程退出的时候被调用。在 Service 类中,只有一个 handle 方法,它的参数就是已经 accept 到 socket 。
要实现这个简单的服务器例子,代码如下:
class SP_ProcUnpService : public SP_ProcInetService {
public:
SP_ProcUnpService() {}
virtual ~SP_ProcUnpService() {}
virtual void handle( int sockfd ) {
int ntowrite;
ssize_t nread;
char line[MAXLINE], result[MAXN];
for ( ; ; ) {
if ( (nread = read(sockfd, line, MAXLINE)) == 0) {
return; /* connection closed by other end */
}
/* line from client specifies #bytes to write back */
ntowrite = atol(line);
if ((ntowrite <= 0) || (ntowrite > MAXN)) {
syslog( LOG_WARNING, "WARN: client request for %d bytes", ntowrite);
exit( -1 );
}
SP_ProcPduUtils::writen(sockfd, result, ntowrite);
}
}
};
class SP_ProcUnpServiceFactory : public SP_ProcInetServiceFactory {
public:
SP_ProcUnpServiceFactory() {}
virtual ~SP_ProcUnpServiceFactory() {}
virtual SP_ProcInetService * create() const {
return new SP_ProcUnpService();
}
virtual void workerInit( const SP_ProcInfo * procInfo ) {
signal( SIGINT, SIG_DFL );
printf( "pid %d start\n", (int)procInfo->getPid() );
}
virtual void workerEnd( const SP_ProcInfo * procInfo ) {
printf( "pid %d exit, pipeFd %d, requests %d, lastActiveTime %ld\n",
(int)procInfo->getPid(), procInfo->getPipeFd(),
procInfo->getRequests(), procInfo->getLastActiveTime() );
}
};
int main( int argc, char * argv[] )
{
SP_ProcMTServer server( "", 1770, new SP_ProcUnpServiceFactory() );
server.start();
return 0;
}


评论 共 0 条 发表评论