www.pudn.com > ProcePool.rar > propool.c
#include "propool.h"
/*************************************************
函数名称∶AcceptWait()
函数功能∶对SemLock的封装
输入参数∶无
输出参数∶无
返 回 值∶0 -- 成功
**************************************************/
int AcceptWait()
{
SemLock(SEMKEY_LOCK); /*信号灯解锁*/
return 0;
}
/*************************************************
函数名称∶AcceptRelease()
函数功能∶对SemLock的封装
输入参数∶无
输出参数∶无
返 回 值∶0 -- 成功
**************************************************/
int AcceptRelease()
{
SemUnlock(SEMKEY_LOCK); /*信号灯解锁*/
return 0;
}
/******************************************************************************
函数名称: InitPool
函数功能: 进程池初始化
输入参数: iInitNum -- 初始化进程数
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int InitPool(int iInitNum)
{
char sFileName[FILENAME_LEN];
int iRet;
int ShmID;
memset(sFileName, 0, sizeof(sFileName));
sprintf(sFileName, "%s/%s/%s", getenv("HOME"), "tmp", KEY_FILE1);
if(fclose(fopen(sFileName, "w")) == -1)
{
return -1;
}
SHMKEY_POOL = ftok(sFileName, 'a');
if(SHMKEY_POOL == -1)
{
printf("Create SHMKEY ERROR:[%s] \n", strerror(errno));
return -2;
}
SHMKEY_POOLCTRL = ftok(sFileName, 'b');
if(SHMKEY_POOLCTRL == -1)
{
printf("Create SHMKEY ERROR:[%s] \n", strerror(errno));
return -3;
}
ShmRemove(SHMKEY_POOL);
ShmRemove(SHMKEY_POOLCTRL);
/*创建共享内存*/
ShmID = ShmCreate(SHMKEY_POOLCTRL, sizeof(PoolCtrl));
if(ShmID < 0 )
{
printf("Create SHM error: [%s]\n", strerror(errno));
return -4;
}
g_SPoolCtrl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
memset(g_SPoolCtrl, 0, sizeof(g_SPoolCtrl));
/*初始化PoolCtrl结构*/
g_SPoolCtrl->EPoolStatus = PSTATUS_ON;
g_SPoolCtrl->iActProcNum = 0;
g_SPoolCtrl->iInitProcNum = iInitNum;
g_SPoolCtrl->iValidProcNum = 0;
g_SPoolCtrl->iMaxProcNum = 0;
/*创建共享内存*/
ShmID = ShmCreate(SHMKEY_POOL, sizeof(Pool) * g_SPoolCtrl->iInitProcNum);
if(ShmID < 0 )
{
printf("Create SHM error: [%s]\n", strerror(errno));
/*释放已创建共享内存的资源*/
ShmUnlink((char *)g_SPoolCtrl);
ShmRemove(SHMKEY_POOLCTRL);
return -5;
}
g_SPool = (Pool *)ShmLink(SHMKEY_POOL);
memset(g_SPool, 0, sizeof(Pool) * g_SPoolCtrl->iInitProcNum);
/*生成信号灯 的键值*/
memset(sFileName, 0, sizeof(sFileName));
sprintf(sFileName, "%s/%s/%s", getenv("HOME"), "tmp", KEY_FILE2);
if(fclose(fopen(sFileName, "w")) == -1)
{
/*释放已创建共享内存的资源*/
ShmUnlink((char *)g_SPoolCtrl);
ShmUnlink((char *)g_SPool);
ShmRemove(SHMKEY_POOL);
ShmRemove(SHMKEY_POOLCTRL);
return -6;
}
SEMKEY_LOCK = ftok(sFileName, 'a');
SemRemove(SEMKEY_LOCK);
SemInit(SEMKEY_LOCK, 1);
return 0;
}
/******************************************************************************
函数名称: IncActProcNum
函数功能: 进程池中激活子进程 增加1
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int IncActProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
SemLock(SEMKEY_LOCK); /*加锁*/
pSPoolCtl->iActProcNum ++;
SemUnlock(SEMKEY_LOCK); /*解锁*/
return 0;
}
/******************************************************************************
函数名称: DecActProcNum
函数功能: 进程池中激活子进程 减少1
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int DecActProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
SemLock(SEMKEY_LOCK);
pSPoolCtl->iActProcNum --;
SemUnlock(SEMKEY_LOCK);
return 0;
}
/******************************************************************************
函数名称: IncValidProcNum
函数功能: 进程池中有效子进程 增加1
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int IncValidProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
SemLock(SEMKEY_LOCK);
pSPoolCtl->iValidProcNum ++;
SemUnlock(SEMKEY_LOCK);
return 0;
}
/******************************************************************************
函数名称: DecValidProcNum
函数功能: 进程池中有效子进程 减少1
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int DecValidProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
SemLock(SEMKEY_LOCK);
pSPoolCtl->iValidProcNum --;
SemUnlock(SEMKEY_LOCK);
return 0;
}
/******************************************************************************
函数名称: GetActProcNum
函数功能: 获取进程池中激活子进程数
输入参数: 无
输出参数: 无
返 回 值: 进程池中激活子进程
******************************************************************************/
int GetActProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
return pSPoolCtl->iActProcNum;
}
/******************************************************************************
函数名称: GetValidProcNum
函数功能: 获取进程池中有效子进程数
输入参数: 无
输出参数: 无
返 回 值: 进程池中激活子进程
******************************************************************************/
int GetValidProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
return pSPoolCtl->iValidProcNum;
}
/******************************************************************************
函数名称: GetInitProcNum
函数功能: 获取进程池中有效子进程数
输入参数: 无
输出参数: 无
返 回 值: 进程池中激活子进程
******************************************************************************/
int GetInitProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
return pSPoolCtl->iInitProcNum;
}
/******************************************************************************
函数名称: GetValidProcNum
函数功能: 获取进程池中有效子进程数
输入参数: 无
输出参数: 无
返 回 值: 进程池中激活子进程
******************************************************************************/
int GetIdleProcNum()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
return pSPoolCtl->iValidProcNum - g_SPoolCtrl->iActProcNum;
}
/******************************************************************************
函数名称: GetPoolStatus
函数功能: 获取进程池状态
输入参数: 无
输出参数: 无
返 回 值: 0 -- 不可用
1 -- 可用
******************************************************************************/
int GetPoolStatus()
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
if(pSPoolCtl->EPoolStatus == PSTATUS_OFF)
{
return 0;
}
else
{
return 1;
}
}
/******************************************************************************
函数名称: SetPoolStatus
函数功能: 获取进程池状态
输入参数: PSTATUS_ON -- 进程池可用
PSTATUS_OFF -- 进程池不可用
输出参数: 无
返 回 值: 0 -- 正常
******************************************************************************/
static int SetPoolStatus(EPoolStatus status)
{
PoolCtrl *pSPoolCtl;
pSPoolCtl = (PoolCtrl *)ShmLink(SHMKEY_POOLCTRL);
pSPoolCtl->EPoolStatus = status;
return 0;
}
/******************************************************************************
函数名称: SetPoolOn
函数功能: 设置进程池为可用状态
输入参数: 无
输出参数: 无
返 回 值: 0 -- 正常
******************************************************************************/
int SetPoolOn()
{
SetPoolStatus(PSTATUS_ON);
return 0;
}
/******************************************************************************
函数名称: SetPoolOff
函数功能: 设置进程池为不可用状态
输入参数: 无
输出参数: 无
返 回 值: 0 -- 正常
******************************************************************************/
int SetPoolOff()
{
SetPoolStatus(PSTATUS_OFF);
return 0;
}
/******************************************************************************
函数名称: GetChildProcInfo
函数功能: 根据进程号获取子进程相关信息
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
******************************************************************************/
int GetChildProcInfo(pid_t pid, Pool *SPool)
{
int i;
Pool *pSPool;
pSPool = (Pool *)ShmLink(SHMKEY_POOL);
for(i = 0; i < GetValidProcNum(); i++)
{
if(pid == pSPool[i].iPid)
{
break;
}
}
memcpy(SPool, pSPool + i, sizeof(Pool));
return 0;
}
/******************************************************************************
函数名称: GetChildProcInfo
函数功能: 根据索引号获取子进程相关信息
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
******************************************************************************/
int GetChildProcInfoIndex(int index, Pool *SPool)
{
Pool *pSPool;
pSPool = (Pool *)ShmLink(SHMKEY_POOL);
memcpy(SPool, pSPool + index, sizeof(Pool));
return 0;
}
/******************************************************************************
函数名称: CreateChildProc
函数功能: 进程池初始化
输入参数: iInitNum -- 初始化进程数
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
static int CreateChildProc(int i, TSocket *sock)
{
Pool *pSPool;
pSPool = (Pool *)ShmLink(SHMKEY_POOL);
printf("CreateChildProc......................begin\n");
pSPool[i].iPid = getpid();
pSPool[i].lRate = 0;
pSPool[i].EStatus = CSTATUS_IDLE;
pSPool[i].lLastTime = 0;
pSPool[i].lPort = sock->LocalPort;
/*有些进程数 +1*/
IncValidProcNum();
return 0;
}
/******************************************************************************
函数名称: CreatePool
函数功能: 进程池初始化
输入参数: func -- 输入函数指针
data -- func函数输入参数
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int CreatePool(int (*func)(int), int iForkFlag, TSocket *sock, LinkNode *link)
{
int i;
pid_t pid;
Module *pSMod;
LinkNode *pNode;
for(i = 0; i < GetInitProcNum(); i ++)
{
SetEnv_tcp(sock, atol(pSMod->port));
switch((pid = fork()))
{
case -1:
fprintf(stderr, "FORK ERROR : [%s] \n", strerror(errno));
ClearIPC();
return -1;
case 0:
CreateChildProc(i, sock);
for(;;)
{
Accept();
}
func();
default:
continue;
}
}
return 0;
}
/******************************************************************************
函数名称: UseChildProc
函数功能: 使用子进程
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int UseChildProc()
{
int i;
pid_t pid;
Pool *pSPool;
pSPool = (Pool *)ShmLink(SHMKEY_POOL);
pid = getpid();
for(i = 0; i < GetValidProcNum(); i ++)
{
if(pSPool[i].iPid == pid)
{
break;
}
}
/*置进程状态为忙碌*/
pSPool[i].EStatus = CSTATUS_ACT;
pSPool[i].lLastTime = atol(GetSysTime());
/*此进程被使用次数 +1*/
pSPool[i].lRate ++;
IncActProcNum();
return 0;
}
/******************************************************************************
函数名称: RlsChildProc
函数功能: 释放子进程
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int RlsChildProc()
{
int i;
pid_t pid;
Pool *pSPool;
pSPool = (Pool *)ShmLink(SHMKEY_POOL);
pid = getpid();
for(i = 0; i < GetValidProcNum(); i ++)
{
if(pSPool[i].iPid == pid)
{
break;
}
}
/*激活进程数减 1*/
DecActProcNum();
/*置进程状态为空闲*/
pSPool[i].EStatus = CSTATUS_IDLE;
return 0;
}
/******************************************************************************
函数名称: MonitorPool
函数功能: 监控进程池
输入参数: 无
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int MonitorPool()
{
int i;
Pool *pSPool;
pSPool = (Pool *)ShmLink(SHMKEY_POOL);
while(1)
{
for(i = 0; i < GetValidProcNum(); i ++)
{
/*
* 如果为异常进程,则重置此子进程
*/
if( pSPool[i].iPid > 0 && kill(pSPool[i].iPid, 0) != 0)
{
pSPool[i].iPid = 0;
pSPool[i].EStatus = CSTATUS_IDLE;
pSPool[i].lRate = 0;
pSPool[i].lLastTime = 0;
}
}
}
}
/******************************************************************************
函数名称: ClearPool
函数功能: 释放进程池
输入参数: iFlag -- 是否强制关闭进程池(即 当子进程正在处理交易时,是否强制关闭它)
1: 当子进程空闲时 才能被杀掉
输出参数: 无
返 回 值: 0 -- 成功
<0 -- 失败
******************************************************************************/
int ClearPool(int iFlag)
{
int i;
time_t t0;
for(i = 0; i < GetValidProcNum(); i ++)
{
if(iFlag == 1)
{
t0 = time(NULL);
while(g_SPool[i].EStatus == CSTATUS_ACT)
{
/*超时时间*/
if(time(NULL) - t0 > OFF_WAITTIME)
{
break;
}
}
}
if(g_SPool[i].iPid > 0)
{
kill(g_SPool[i].iPid, SIGTERM);
}
}
ClearIPC();
free(g_SPool);
free(g_SPoolCtrl);
return 0;
}