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

恋喵大鲤鱼
博客专家认证
2015-09-11 03:56:27
程序编译运行环境:
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;
}

...全文
254 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
nswcfd 2015-09-14
  • 打赏
  • 举报
回复
top的第一个进程? S状态应该是在等待什么事件吧? 可以看看wait在什么地方。估计跟IO有关系。
zhxianbin 2015-09-13
  • 打赏
  • 举报
回复
会不停的 fork -exec 吗?
Arnold9009 2015-09-12
  • 打赏
  • 举报
回复
看看慢的时候,cpu的各个核是不是使用率都很高
恋喵大鲤鱼 2015-09-12
  • 打赏
  • 举报
回复
引用 3 楼 Arnold9009 的回复:
看看慢的时候,cpu的各个核是不是使用率都很高

下面这个截图是top命令显示的信息,此时execl卡住了,正在阻塞,但是cpu的使用率也没有很高吧?
恋喵大鲤鱼 2015-09-11
  • 打赏
  • 举报
回复
引用 1 楼 zhxianbin 的回复:
重启电脑后,就不会出现,但是运行一段时候后又会出现 看起来 CPU 被占用了
引用 1 楼 zhxianbin 的回复:
重启电脑后,就不会出现,但是运行一段时候后又会出现 看起来 CPU 被占用了
能具体说明内在的机制吗?那如何解决这个问题呢?我这个程序需要运行很长时间,长则几个月,服务器一般不能重启的,该如何解决呢?
zhxianbin 2015-09-11
  • 打赏
  • 举报
回复
重启电脑后,就不会出现,但是运行一段时候后又会出现 看起来 CPU 被占用了

18,773

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 专题技术讨论区
社区管理员
  • 专题技术讨论区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧