您的位置: 新闻频道 开源新闻

原创新闻 SPProcPool 0.5 发布

2008-01-05 by 见习记者 iunknown
评论(0) 有357人浏览 进程池 prefork
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 版新增的服务器模型。这个类定义如下:

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 条 发表评论

发表评论

您还没有登录,请登录后发表评论