Вилка Бесконечный цикл - PullRequest
1 голос
/ 07 апреля 2011

Я пытаюсь создать программу мониторинга каталогов на C. До сих пор она обнаруживает подкаталоги основного каталога, однако проблема возникает, когда я пытаюсь отслеживать подкаталоги подкаталогов.

char * const  son[] = { argv[0], name, NULL };  

pid_t pid = fork();
if (pid == 0) {
    execvp(son[0], son);
}

Этот код должен был создать дочерний процесс, который контролировал бы подкаталоги.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 ]

2 голосов
/ 07 апреля 2011

У вас есть программа, которая разветвляется, а затем запускает новую собственную копию. Думайте об этом как о бесконечной рекурсии. Нет необходимости выполнять новый экземпляр, просто напишите свой код, чтобы программа продолжала идти по одному из двух путей в зависимости от возвращенного идентификатора процесса.

Но это не правильное решение.

Правильное решение - не раскошелиться вообще. Вы почти не получаете выгоды от наличия тысячи процессов, которые смотрят на один каталог, по сравнению с одним процессом, который смотрит на тысячу каталогов. На самом деле, вы можете быть намного хуже, загружая планировщик.

1 голос
/ 07 апреля 2011

Похоже, ты всегда вилка, несмотря ни на что.Я бы поставил там галочку, чтобы убедиться, что если у вас нет подкаталогов в текущем каталоге, вы не разветвляетесь.

0 голосов
/ 07 апреля 2011

Вы разветвляете дочерний процесс, но что делает родительский процесс после вызова fork()? Кажется, вы хотите рекурсивно разветвить процессы, но для того, чтобы это работало правильно, вам придется выполнитьследующее:

1) Проверьте, есть ли какие-либо подкаталоги в текущем каталоге ... если их нет, то exit(), в противном случае прочитайте все подкаталоги в текущемdirectory.

2) Для каждого подкаталога разветвляется процесс.Если ответвление является дочерним (т. Е. pid == 0), сделайте вызов execvp().

3) Если pid != 0, значит, вы находитесь в родительском процессе.Вместо того, чтобы пытаться спать в течение некоторого периода времени, позвоните на wait() и продолжайте повторять вызов на wait(), пока не останутся дочерние процессы.

4) После того, как нет дочерних процессов-процессы слева (т. е. wait() возвращает состояние ошибки, такое что errno == ECHILD), затем вы можете позвонить на exit() в родительском процессе.

Так что, если вы выполните эти 4 шага, выне должно возникать никаких бесконечных петель.Каждый дочерний процесс в какой-то момент завершится, как только он достигнет каталога, в котором больше нет подкаталогов, и каждый родительский процесс будет ждать, пока его дочерние процессы не завершатся, так что вы не получите никаких потерянных процессов.Если вы в конечном итоге получите бесконечный цикл, то это потому, что дочерний процесс не завершается, что будет указывать на логику, используемую для определения наличия подкаталогов в текущем каталоге, или вы не обнаружите это должным образом.больше нет ни одного ребенка, ожидающего в родительском процессе.

Надеюсь, это поможет,

Джейсон

...