我正试着写一个程序来读取一堆unix命令,并创建子进程来执行它们.它有一个参数来确定我希望同时运行的子进程的最大数量.我将stdin
重定向到一个单独的文件中,该文件中充满了这样的命令:./a.out 3 < batchcmds
.当我运行代码时,它会一遍又一遍地重读所有命令,但是当我注释掉switch语句时,它会按预期运行(当然,创建进程和运行命令除外).我已经通过测试确认,所有的子进程在到达while循环的末尾之前就终止了,所以主进程一定是被某种方式搞砸了,导致它重复读取一个文件.下面是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int makearg(char*, char***);
#define BUFFERSIZE 1024
int main(int argc, char** argv) {
// reads argument
int maxpc = atoi(argv[1]);
int pc = 0;
// read from the file and assign it to a child
char command[BUFFERSIZE];
while(fgets(command, 128, stdin) > 0) {
char** args;
makearg(command, &args);
if(pc >= maxpc) {
wait(NULL);
pc--;
}
switch(fork()) { // When I comment out from here to the comment below it works as expected
case 0:
// is child
execvp(args[0], args);
printf("execv failed to run %s", command);
exit(0);
printf("child is immortal\n");
return -1;
case -1:
printf("failed to create child\n");
break;
default:
// is parent
pc++;
} // The comment below
printf("end while loop: %x:%s", getpid(), command);
}
// wait for children to finish
for(; pc > 0; pc--) wait(NULL);
return 0;
}
int makearg(char* s, char*** args) {
// count the tokens in the string
int tokencount = 1;
int slength = 1;
for(char* c = s; *c != '\0'; c++) {
if(*c == ' ')
tokencount++;
slength++;
}
// set up the array of tokens
char** tokens = (char**)malloc(tokencount*sizeof(char*));
if(tokens == NULL) {
return -1;
}
for(int i = 0; i < tokencount; i++)
tokens[i] = (char*)malloc(slength*sizeof(char));
if(tokens == NULL) {
for(int i = 0; i < tokencount; i++)
free(tokens[i]);
free(tokens);
return -1;
}
// copy data over to the token array
int itoken = 0;
int ichar = 0;
for(char* c = s; *c != '\0'; c++) {
if(*c == ' ') {
tokens[itoken][ichar] = '\0';
itoken++;
ichar = 0;
}
else if(*c != '\n') {
tokens[itoken][ichar] = *c;
ichar++;
}
}
tokens[itoken][ichar] = '\0';
*args = tokens;
return tokencount;
}
这真的把我难住了,我找不到任何人有类似的问题.任何帮助将不胜感激!