[原]Linux ExecFun
//轉載必須注明
//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;
}
//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;
}
posted on 2012-07-05 09:30 天下 閱讀(373) 評論(0) 編輯 收藏 引用 所屬分類: Linux編程