//转载必须注明
//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:执行成功 ,false:执行失败
//参数说明:
//pfnExec 回调函数
//pArg 回调函数的参数
//pnStatus 把pfnExec执行的返回值,返回给pnStatus指向的变量
//dwTimeOut 执行的超时时间,单位毫秒(1秒=1000毫秒)
//bKill 超时退出时,是否杀死子进程.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;
}