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;
}
6 个解决方案
#1
重启电脑后,就不会出现,但是运行一段时候后又会出现
看起来 CPU 被占用了
看起来 CPU 被占用了
#2
能具体说明内在的机制吗?那如何解决这个问题呢?我这个程序需要运行很长时间,长则几个月,服务器一般不能重启的,该如何解决呢?
#3
看看慢的时候,cpu的各个核是不是使用率都很高
#4
下面这个截图是top命令显示的信息,此时execl卡住了,正在阻塞,但是cpu的使用率也没有很高吧?
#5
会不停的 fork -exec 吗?
#6
top的第一个进程? S状态应该是在等待什么事件吧?
可以看看wait在什么地方。估计跟IO有关系。
可以看看wait在什么地方。估计跟IO有关系。
#1
重启电脑后,就不会出现,但是运行一段时候后又会出现
看起来 CPU 被占用了
看起来 CPU 被占用了
#2
能具体说明内在的机制吗?那如何解决这个问题呢?我这个程序需要运行很长时间,长则几个月,服务器一般不能重启的,该如何解决呢?
#3
看看慢的时候,cpu的各个核是不是使用率都很高
#4
下面这个截图是top命令显示的信息,此时execl卡住了,正在阻塞,但是cpu的使用率也没有很高吧?
#5
会不停的 fork -exec 吗?
#6
top的第一个进程? S状态应该是在等待什么事件吧?
可以看看wait在什么地方。估计跟IO有关系。
可以看看wait在什么地方。估计跟IO有关系。