天下

记录修行的印记

[原]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;
}

posted on 2012-07-05 09:30 天下 阅读(241) 评论(0)  编辑 收藏 引用 所属分类: Linux编程


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2020年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

导航

统计

常用链接

留言簿(4)

随笔分类(377)

随笔档案(327)

链接

最新随笔

搜索

最新评论