叉无限循环

时间:2011-04-07 15:56:56

标签: c exec fork infinite-loop

我正在尝试在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_name\n", 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%d\n", 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%s\n",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);
}

3 个答案:

答案 0 :(得分:2)

你有一个程序可以分叉然后运行它自己的新副本。把它想象成无休止的递归。无需执行新实例,只需编写代码,以便程序根据返回的进程ID继续执行两个路径之一。

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

正确的解决方案根本不是分叉。拥有一千个查看一个目录的进程,而不是查看一千个目录的单个进程,几乎没有任何好处。实际上,通过在调度程序上加载负载可能会更糟糕。

答案 1 :(得分:1)

看起来你无论如何总是叉。我会在那里放一张支票,以确保如果当前目录中没有子目录,那么你就不用叉子。

答案 2 :(得分:0)

你正在分配一个子进程,但是在调用fork()?之后父进程做了什么似乎你想要递归地分叉进程,但是为了使它正常工作,你将不得不 - 如下:

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

2)为每个子目录分叉一个进程。如果分叉是孩子(即pid == 0),则拨打execvp()

3)如果是pid != 0,那么您就在父进程中。而不是试着睡一段时间,打电话给wait(),并继续重复调用wait(),直到没有子进程离开。

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

因此,如果您遵循这4个步骤,则不应该产生任何无限循环。每个子进程一旦到达不再有子目录的目录就会在某个时刻退出,并且每个父进程在退出之前都会等待它的子进程,这样您就不会得到任何孤立的进程。如果你最终得到一个无限循环,那是因为子进程没有退出,这将指向用于检测当前目录中是否有任何子目录的逻辑,或者你没有正确检测到在父进程中不再有任何孩子等待。

希望这有帮助,

杰森