`
yuanyu5237
  • 浏览: 159672 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一个多进程框架

 
阅读更多

从别处找来的,记一下,学习~

/*=============================================================================
#
#   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);
}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics