最后更新于 .

写了一个简单的多进程的框架,其实很简单但是意义却不仅在于此。
一.网上弄够编译通过的这种代码几乎=0,都是象征性的贴几段代码,直接拿下来,编都编译不过。
二.近期打算写一个基于epoll网络模型的服务器框架,前端网络接入全部由框架完成,而收到包之后的业务逻辑交给业务自己完成,这里的业务逻辑的进程数是可以动态调整的,所以用到了fork进程的概念(因为线程对代码编写要求太高)

好了代码如下(在文章末尾会直接放出代码下载,在suse linux 10下编译通过):

 /*==============================================
#
#   Author:            dantezhu – zny2008@gmail.com
#
#   QQ :                327775604
#
#   Last modified:  2009-11-05 19:30
#
#   Filename:        forkwork_use.cpp
#
#   Description:    多进程的一个框架,大家可以直接使用,已经经过功能测试和压力测试。
#                        编译:g++ forkwork_use.cpp -o forkwork_use 
#                        (实际上看过我写的 VIM-一键编译单个源文件 的话,直接按下F5就行了)
#
================================================*/
#include <iostream>
#include <pthread.h>
#include <asm/atomic.h>
#include <string>
#include <vector>
#include <sys/time.h>
#include <asm/atomic.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <map>
using namespace std;
//==============================================
typedef std::pair<pid_t,int> pidPair;
map<pid_t,int> g_MapPids;int DoYourWork(int iIndex);
/** 
   * @brief       检查子进程情况(不需要改动)
   * 
   * @param    bNeedCon     true:父进程发现子进程死掉就会重新拉起子进程;
   *                                      false:父进程在所有子进程都退出之后也会退出。
   * 
   * @return    0           succ
   *                 else        fail
*/
int DetectPids(bool bNeedCon)
{
    pid_t pid;
    pid_t _n_pid;
    int Ret;
    for(;;)
    {
        //会阻塞在这里,等待有子进程退出
        pid = waitpid(-1,NULL,0);
        if ( pid < 0 )
        {
            sleep(1);
            continue;
        }
        if(!bNeedCon)//等待结束
        {
            g_MapPids.erase(pid);
            if(g_MapPids.size()==0)
                return 0;
        }
        else//检测拉起
        {
            if(g_MapPids.count(pid)<=0)
            {
                sleep(1);
                continue;
            }
            int index=g_MapPids.find(pid)->second;
            g_MapPids.erase(pid);
            _n_pid = fork();
            if(_n_pid<0)
            {
                sleep(1);
                continue;
            }
            else if ( _n_pid == 0 )
            {
                printf(“i am child\n”);
                g_MapPids.clear();
                Ret = DoYourWork(index);    
                return Ret;
            }
            else
            {
                printf(“i am farther,child is %d,index is %d\n”,_n_pid,index);
                g_MapPids.insert(pidPair(_n_pid,index));
            }
            sleep(1);
        }
    }
    return 0;
}
/** 
 * @brief       执行启动多个子进程的逻辑(不需要改动)
 * 
 * @param    forknum               子进程个数
 * @param    bNeedCon            true:父进程发现子进程死掉就会重新拉起子进程;
 *                                             false:父进程在所有子进程都退出之后也会退出。
 * 
 * @return    0                succ
 *                 else            fail
 */
int ForkWork(int forknum,bool bNeedCon)
{
    g_MapPids.clear();
    pid_t pid=0;
    int Ret;
    for(int i=0;i<forknum;++i)
    {
        pid=fork();
        if(pid==-1)
            return -1;//err
        else if(pid==0)//child
        {
            //执行
            printf(“i am child\n”);
            g_MapPids.clear();
            Ret = DoYourWork(i);
            return Ret;
        }
        else
        {
            printf(“i am farther,child is %d,index is %d\n”,pid,i);
            g_MapPids.insert(pair<pid_t,int>((pid_t)pid,(int)i));
        }
    }
    printf(“start all pids and start detect\n”);
    DetectPids(bNeedCon);
    return 0;
}
/** 
 * @brief       用户需要执行的函数(需要用户实现)
 * 
 * @param    iIndex     给这个进程分配一个userId,存储在父进程的pid->userId的映射表里;
 *                               主要目的是为了实现当子进程自己死掉,父进程可以重新根据map表传入这个userId
 * 
 * @return    0            succ
 *                 else        fail
 */
int DoYourWork(int iIndex)
{
    //do your ownthing
    sleep(5);
    return 0;
}
int main(int argc,char ** argv)
{
    if(argc < 2)
    {
        printf(“please input maxforknum needCon(0/1)\n”);
        printf(“eg. ./forkwork_use 10 1\n”);
        return 0;
    }
    int iForkNum=atoi(argv[1]);
    bool bNeedCon=atoi(argv[2]);
    ForkWork(iForkNum,bNeedCon);
}

执行结果如下:

fork

 forkwork_use.cpp下载
后续会慢慢开始新框架的编写,欢迎大家提出意见。

 

Pingbacks

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. 王济尧

    王济尧 on #

    你好,想问一下这个判断有什么用?
    if(g_MapPids.count(pid)&lt;=0)
    {
    sleep(1);
    continue;
    }

    Reply

发表评论