我正在编写一个程序,可以从文件中读取linux
命令,并使用fork()
和execvp()
并行运行它们,它工作得很好。
while((current = GetNextCommand(current)) != NULL){
char currentCommand[WIDTH - 1];
current->active = true;
strcpy(currentCommand, current->command);
int j=0;
int ctr=0;
char newString[LENGTH][WIDTH];
for(int i = 0; i <= strlen(currentCommand); i++){
// if space or NULL found, assign NULL into newString[ctr]
if(currentCommand[i]==' '|| currentCommand[i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j] = currentCommand[i];
j++;
}
}
char *exe[ctr + 1];
for(int i = 0; i < ctr; i++){
exe[i] = strdup(newString[i]);
}
exe[ctr] = NULL;
t = clock();
clock_gettime(CLOCK_MONOTONIC, &start);
current->starttime = start.tv_sec;
current->PID = (pid = fork());
if(pid < 0){
fprintf(stderr, "fork Failed\n"); //output in stderr if fork fails and return
exit(1);
}
else if(pid == 0){
execvp(exe[0], exe);
//fails
exit(2);
}
}
我的档案是
sleep 3
ls -latr
sleep 1
pwd
sleep 1
wc /etc/passwd
sleep 10
在父进程中,我需要获取每个子进程的运行时间,如果命令的运行时间大于2秒,我将重新运行该命令,如果命令的运行时间大于2秒,我将继续运行该命令,直到用户使用kill -sig pid
或pkill sleep
杀死该进程。我使用for循环,并设置相应的等待数(&status).在我的文件中,sleep 3
和sleep 10
将大于2秒,当sleep 3
的进程完成工作后,它将返回父进程,sleep 10
仍在运行,当我现在使用pkill sleep
时,它将很好,因为sleep 10
将继续在父进程中运行,但是,当它们都从子进程中退出,而我使用kill -sig pid
时,整个程序退出。那么,在这种情况下,我如何同时运行它们(sleep 3
和sleep 10
)呢?
for(int i = 0; i < nodeIndex - 1; i++){
int status;
int pid = wait(&status);
clock_gettime(CLOCK_MONOTONIC, &finish);
CommandNode* cNode;
cNode = FindCommand(head->nextCommandPtr, pid);
elapsed = finish.tv_sec - cNode->starttime;
printf("%ld\n", elapsed);
if(elapsed < 2){
cNode->active = false;
}
else{
char rerunCommand[WIDTH - 1];
strcpy(rerunCommand, cNode->command);
int j=0;
int ctr=0;
char newString[LENGTH][WIDTH];
for(int i = 0; i <= strlen(rerunCommand); i++){
// if space or NULL found, assign NULL into newString[ctr]
if(rerunCommand[i]==' '|| rerunCommand[i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j] = rerunCommand[i];
j++;
}
}
char *exe[ctr + 1];
for(int i = 0; i < ctr; i++){
exe[i] = strdup(newString[i]);
}
exe[ctr] = NULL;
while(elapsed > 2){
int pid2;
t = clock();
clock_gettime(CLOCK_MONOTONIC, &start);
cNode->starttime = start.tv_sec;
cNode->PID = (pid2 = fork());
if(pid2 < 0){
fprintf(stderr, "fork Failed"); //output in stderr if fork fails and return
exit(1);
}
else if(pid2 == 0){
printf("What happened here.\n");
execvp(exe[0], exe);
exit(2);
}
else{
wait(&status);
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = finish.tv_sec - cNode->starttime;
if(elapsed > 2) {
printf("What is this: %d %d\n", pid2, cNode->PID);
}
}
}
}
}
2条答案
按热度按时间m2xkgtsf1#
关于标题中的问题:
是的,你可以,只是循环,直到返回值是-1
py49o6xq2#
是的,这确实是一个正确的方法,以确保您所有的孩子已经完成之前,您继续:
这是僵尸进程的旧遗产(就像行尸走肉电影的片名):僵尸进程是一个进程,它已经
exit(2)
艾德但是它的父进程还没有wait(2)
。除了它的进程表条目(其中存储了它的退出代码和记帐记录)之外,它释放了它的所有资源。这样,当父进程执行wait(2)
系统调用时,内核可导航其子进程的表并检查其是否必须返回错误(如果列表为空),或者某个子进程已经结束,可以将它的exit(2)
代码返回给父进程。只有在您以前创建过fork(2)
的情况下,才能正确使用wait(2)
(例如,没有错误)。并且wait(2)
在您没有创建子进程的情况下发出错误信号。要获得子进程的运行时间,您需要使用
wait(2)
的一个备用系统调用(wait3(2)
或wait4(2)
,根据FreeBSD手册页,Linux上有类似的系统调用)试试这个简单的例子:
以及一个执行的一个示例: