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; 
}