C语言 分叉无限循环



我试图在c中制作一个目录监控程序。到目前为止,它检测主目录的子目录,但是当我试图监控子目录的子目录时,问题就发生了。

char * const  son[] = { argv[0], name, NULL };  
pid_t pid = fork();
if (pid == 0) {
    execvp(son[0], son);
}

这段代码应该创建一个子进程来监视子目录。例如,name为字符串,子目录为"Desktop/test"。我之前试着打印"name",它是我想要的子目录,所以问题不在这里。

程序运行完美,直到我添加这个。一旦我添加了它,它就会进入一个无限循环,尽管之前是有效的。我还想指出,我不使用信号,所以问题不是来自信号。

这当然只是代码的摘录。如果你认为我需要发布完整的代码,这是大得多,我会添加它,虽然老实说我怀疑问题是在它,因为它以前工作得很好。

编辑:最好添加所有的代码,argv[1]是目录,argv[2]表示我希望程序运行多少分钟,argv[3]表示每次扫描之间的暂停时间。如果我删除上面的摘录,它可以工作,我知道这有点令人困惑,但如果你有任何问题,请说。

int main(int argc, char *argv[]) {

char** direc;
int direct_pos = 0;
direc = (char**) malloc(2 * sizeof(char*));

double actual_time = 0;
double MAXTIME = atof(argv[2]);
MAXTIME = MAXTIME * 60;
double IterationTime = atof(argv[3]);
time_t start = time(0);

char dot2[100];
char dot[100];
sprintf(dot, "%s/.", argv[1]); 
sprintf(dot2, "%s/..", argv[1]); 
direct_pos++;
direc[direct_pos - 1] = (char*) malloc(strlen(dot) * sizeof(char));
strcpy(direc[direct_pos - 1], dot);
direct_pos++;
direc[direct_pos - 1] = (char*) malloc(strlen(dot2) * sizeof(char));
    strcpy(direc[direct_pos - 1], dot2);
if (argc != 4) {
    fprintf(stderr, "Usage: %s dir_namen", argv[0]);
    exit(1);
}
while (actual_time < MAXTIME) {
    DIR *dirp;
    if ((dirp = opendir(argv[1])) == NULL) {
        perror(argv[1]);
        exit(2);
    }
    struct stat stat_buf;
    struct dirent *direntp;
    while ((direntp = readdir(dirp)) != NULL) {
        char name[100];
        sprintf(name, "%s/%s", argv[1], direntp->d_name);   
        if (lstat(name, &stat_buf) == -1)  
        {
            perror("lstat ERROR");
            exit(3);
        }
        if (S_ISDIR(stat_buf.st_mode)) 
                      {
            int x;
            for (x = 0; x <= direct_pos; x++) {
                if (x == direct_pos) {
                    char**newarray;
                    newarray = (char**) malloc((direct_pos + 1)* sizeof(char*));
                    int l;
                    for (l = 0; l < direct_pos; l++) {
                                            //printf("nxxxx%dn", sizeof(direc[l]));
                        newarray[l] = (char*) malloc((strlen(direc[l])+1)
                                * sizeof(char));

                        strcpy(newarray[l], direc[l]);
                    }
                    direc = newarray;
                    direc[direct_pos] = (char*) malloc(sizeof(name)
                            * sizeof(char));
                    direc[direct_pos] = strcpy(direc[direct_pos], name);
                    direct_pos++;
                    double seconds_since_start = difftime(time(0), start);
                    double new_time = (MAXTIME - seconds_since_start) / 60;
                    char time_array[10];
                                          sprintf(time_array,"%f",new_time);
                    char * const  son[] = { argv[0], name, time_array,
                            argv[3], NULL };


           printf("n%sn",son[1]);
    x = direct_pos + 2;     
            pid_t pid = fork();
    if (pid == 0) {
         execvp(son[0], son)==-1);
                      break;
                             }
                } else if (strcmp(name, direc[x]) == 0) {
                    x = direct_pos + 2;
                }
            }
        }

    }
    sleep(IterationTime);
    actual_time += IterationTime;
    closedir(dirp);
}
exit(0);
}

您有一个程序分叉,然后运行它自己的新副本。把它想象成无穷递归。不需要执行新实例,只需编写代码,以便程序根据返回的进程ID从两条路径中选择一条继续执行。

但这不是正确的解决方案。

正确的解决方案是根本不分叉。与查看1000个目录的单个进程相比,使用1000个进程查看一个目录几乎没有任何好处。实际上,如果将负载放在调度器上,情况可能会更糟。

看起来无论如何你总是分叉。我要在这里加个检查以确保当前目录下没有子目录时不会分叉

您正在分叉子进程,但是父进程在调用fork()?后做什么?似乎您想要递归地分叉进程,但为了使其正常工作,您将不得不做以下事情:

1)检查当前目录下是否有子目录…如果没有,则读取exit(),否则读取当前目录下的所有子目录

2)对于每个子目录fork一个进程。如果fork是子进程(即pid == 0),则调用execvp()

3)如果pid != 0,那么您在父进程中。与其尝试休眠一段时间,不如调用wait(),并不断重复对wait()的调用,直到没有子进程剩余。

4)一旦没有子进程(即,wait()返回一个错误状态,errno == ECHILD),那么你可以在父进程中调用exit()

所以如果你遵循这4个步骤,你应该不会产生任何无限循环。当每个子进程到达一个没有子目录的目录时,它们都会在某个时候退出,而每个父进程在退出之前都会等待它的子进程,这样就不会出现孤立的进程。如果你确实以一个无限循环结束,那是因为一个子进程没有退出,这将指向用于检测当前目录中是否有任何子目录的逻辑,或者你没有正确检测到在父进程中不再有任何子进程等待。

希望有帮助,

杰森

最新更新