最后更新于 .

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

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

?/*==============================================
#
#???Author:????????????dantezhu – [email protected]
#
#???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

发表评论