从别处找来的,记一下,学习~
/*=============================================================================
#
# Description: 多进程的一个框架,大家可以直接使用,已经经过功能测试和压力测试。
# 编译:g++ forkwork_use.cpp -o forkwork_use
#
=============================================================================*/
#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
#include <sys/time.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 own thing
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);
}