开发者社区> 问答> 正文

Linux下系统调用execl会等待一段时间才执行指定的可执行程序?

程序编译运行环境:
Red Hat Enterprise Linux Server release 6.4 64bits
问题描述:
fork子进程后,使用execl或者execlp调用可执行程序会出现等待一段时间才进入可执行程序,为什么会出现等待,有猿友遇到这个问题吗?很是奇怪,并非每一次都会出现这样的问题,如果重启电脑后,就不会出现,但是运行一段时候后又会出现。
主要代码:

 Result* ALGJob::computation(ComputationTask *task, OriginalTask *original_task) {
    CHECK_NOTNULL(task);
    CHECK_NOTNULL(original_task);
    ALGComputationTask *ALG_task = static_cast<ALGComputationTask*>(task);
    ALGOriginalTask *ALG_original_task = static_cast<ALGOriginalTask*>(original_task);
    ALGResult* ALG_Result=new ALGResult;//用于接受子进程返回的计算结果
    ALG_Result->init();
    cout<<endl<<"-----------------------------------------------------------start computation---------------------------------------------"<<endl;
    sighandler_t old_handler;
    old_handler=signal(SIGCHLD,SIG_DFL);
    string cacheStr = getCacheContext(task, original_task);
    uint64 cache_len = cacheStr.length()+1;
    cout << "compute node cache len " << cache_len << endl;
    pid_t pid;//子进程ID
    int shmid;//共享内存ID
    ALGOriginalTask* ALG_shm_addr=NULL;
    ALGResult* ALG_Result_shm_addr=NULL;
    char *share_cache = NULL;
    void* shm_addr=NULL;//共享内存首地址
    if((shmid=shmget(IPC_PRIVATE,sizeof(ALGOriginalTask)+sizeof(ALGResult)+sizeof(char)*cache_len,IPC_CREAT|0640))<0)//创建当前进程的父子进程私有共享内存
    {
      perror("shmget");
      exit(-1);
    } 
    if((shm_addr=shmat(shmid,0,0))==(void*)-1) {
           perror("Parent:shmat");
           exit(-1);
    }
    else
        memset(shm_addr,NULL,sizeof(ALGOriginalTask)+sizeof(ALGResult)+sizeof(char)*cache_len); 
    switch(pid=fork())
    {
      case -1:
        perror("fork");
        exit(-1);
      case 0://child
      {
        pid_t ppid=getppid();
        pid_t childpid=getpid();
        cout<<"in computation child process"<<endl;
        cout<<"ppid:"<<ppid<<" pid:"<<childpid<<endl;
        //构造ALG.out参数
        string shmId=itoa(shmid);
        string plain_num=itoa(ALG_task->plain_num);
        string plain_len=itoa(ALG_task->plain_len);
        cout<<"in computation child plain_num:"<<plain_num<<endl;
        cout<<"in computation child plain_len:"<<plain_len<<endl;

        const char* argv[4]={"./ALG.out",shmId.c_str(),plain_num.c_str(),plain_len.c_str()};                       
        cout<<"-----------------start the atomic charset computation-------------------"<<endl;
        if(execl(argv[0], argv[0], argv[1], argv[2], argv[3], NULL)==-1)//会卡一段时间再进入ALG.out
            perror("execl error!!!");
        cout<<"-----------------end the atomic charset computation-------------------"<<endl;
        exit(0);
      }
      default://parent
      {
        cout<<"in computation parent process"<<endl;
        cout<<"cpid:"<<pid<<endl;
        //set share memory form 
        ALG_shm_addr=static_cast<ALGOriginalTask*>(shm_addr);
        pthread_mutex_init(&ALG_shm_addr->mutex,NULL); 
        perror("init shm in parent");
        pthread_mutex_lock(&ALG_shm_addr->mutex);
        perror("lock shm in parent ");

        //initialize originalTask
        ALG_shm_addr->algorithm=ALG_original_task->algorithm;
        ALG_shm_addr->encodeType=ALG_original_task->encodeType;
        ALG_shm_addr->cipher_num=ALG_original_task->cipher_num;
        ALG_shm_addr->cipher_len=ALG_original_task->cipher_len;
        ALG_shm_addr->salt_len=ALG_original_task->salt_len;
        //memcpy(ALG_shm_addr->task_name,ALG_original_task->task_name,20);
        memcpy(ALG_shm_addr->cipher,ALG_original_task->cipher,128*256);
        memcpy(ALG_shm_addr->salt,ALG_original_task->salt,128*32);
        memcpy(ALG_shm_addr->re,ALG_original_task->re,32*256);

        void* cache_p = shm_addr + sizeof(ALGOriginalTask);
        share_cache = (char*)cache_p;
        memcpy(share_cache, cacheStr.c_str(), cache_len);

        perror("in parent end write shm");
        pthread_mutex_unlock(&ALG_shm_addr->mutex);
        perror("in parent unlock");

        int status;
        //sighandler_t old_handler;
        old_handler=signal(SIGCHLD,SIG_DFL);

        cout << "computation parent wait child process" << endl;
        //下面有可能会出错
        int ret = waitpid(pid,&status,0);//waiting for the child process finish
        cout << " wait pid return is " << ret << endl;
        if (WCOREDUMP(status)) {
            cout << "child core dump" << endl;
        }
        perror("in parent waitpid:");
        signal(SIGCHLD,old_handler);

        cout<<"child process exit normal with status: "<<status<<endl;
        ALG_Result_shm_addr=static_cast<ALGResult*>(shm_addr);
        //read the result form share memory
        memcpy(&ALG_Result->ts,&ALG_Result_shm_addr->ts,sizeof(struct timeval));
        memcpy(&ALG_Result->te,&ALG_Result_shm_addr->te,sizeof(struct timeval));

        ALG_Result->success_num=ALG_Result_shm_addr->success_num;
        memcpy(ALG_Result->ret_plain,ALG_Result_shm_addr->ret_plain,128*64);


    //删除父进程的共享内存映射地址
        if (shmdt(shm_addr)<0) {
            perror("Parent:shmdt");
            exit(1);
        }
        if (shmctl(shmid,IPC_RMID,NULL)==-1)//delete the share memory
        {
            perror("shmct:IPC_RMID");
            exit(-1);
        }
      }
    }//end fork

    ALG_Result->algorithm=ALG_original_task->algorithm;
    memcpy(ALG_Result->cipher,ALG_original_task->cipher,128*256);
    memcpy(ALG_Result->salt,ALG_original_task->salt,128*32);
    ALG_Result->regulation_index = ALG_task->regulation_index;
    cout << "-----------------------------------------------end computation----------------------------------------------------- " << endl;
    return ALG_Result;
} 

展开
收起
杨冬芳 2016-07-13 13:03:29 2433 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
Alibaba Cloud Linux 3 发布 立即下载
ECS系统指南之Linux系统诊断 立即下载
ECS运维指南 之 Linux系统诊断 立即下载