//轉(zhuǎn)載必須注明
//Aaron.xu
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
unsigned int GetTickCount(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec*1000 + tv.tv_usec/1000);
}
typedef int (*ExecFunProc)(void* pArg);
int mysleep(void* pArg)
{
sleep(4);
return 2;
}
//返回值: true:執(zhí)行成功 ,false:執(zhí)行失敗
//參數(shù)說明:
//pfnExec 回調(diào)函數(shù)
//pArg 回調(diào)函數(shù)的參數(shù)
//pnStatus 把pfnExec執(zhí)行的返回值,返回給pnStatus指向的變量
//dwTimeOut 執(zhí)行的超時(shí)時(shí)間,單位毫秒(1秒=1000毫秒)
//bKill 超時(shí)退出時(shí),是否殺死子進(jìn)程.true:殺死,false:不殺死
bool ExecFun(ExecFunProc pfnExec,void* pArg,int* pnStatus,unsigned int dwTimeOut,bool bKill = false)
{
pid_t childPid;
pid_t tempPid;
int nStatus = 0;
int bRet = 0;
unsigned int dwEndTime = GetTickCount() + dwTimeOut;
assert(pfnExec!=NULL);
assert(pnStatus!=NULL);
*pnStatus = -1;
if( (childPid = fork()) < 0 )
{
printf("fork error:%d \r\n",errno);
return false;
}
if(childPid == 0)
{
printf("at %u,child pid:%d Entry\r\n",GetTickCount(),getpid());
nStatus = pfnExec(pArg);
printf("at %u,child pid:%d Exit(%d)\r\n",GetTickCount(),getpid(),nStatus);
exit(nStatus);
}
else
{
while( 1)
{
usleep(50*1000);
tempPid = waitpid(childPid,&nStatus,WNOHANG);
if (tempPid<0)
{
printf("waitpid(%d) execption,errno:%d \r\n",childPid,errno);
return false;
}
if (tempPid>0)
{
nStatus = WEXITSTATUS(nStatus);
printf("waitpid(%d) normal exit(%d)\r\n",childPid,nStatus);
*pnStatus = nStatus;
return true;
}
if (GetTickCount()>dwEndTime)
{
printf("at %d,waitpid(%d) time out exit\r\n",GetTickCount(),childPid);
if (bKill && (kill(childPid,SIGKILL)==0))
{
wait(&nStatus);
}
return false;
}
}
return false;
}
}
int main() {
int nRet = 0;
bool bRet = ExecFun(mysleep,NULL,&nRet,2000,true);
printf("line:%d , bRet:%d,nRet:%d \r\n",__LINE__,bRet,nRet);
//puts(strerror(EINTR));
return 0;
}