Использование wait() против waitpid() в c

Итак, я пытаюсь пройти по каталогу (и подкаталогам) и создать новые процессы для сортировки файлов и обхода подкаталогов. Однако у меня возникли небольшие проблемы с пониманием того, насколько полезным будет мой код. Насколько я понимаю, wait() будет спать родительский процесс, пока дочерний процесс не завершится. В настоящее время моя рекурсивная функция

void iterate_dir(char* name){

    DIR *dd = opendir(name);
    struct dirent *curr;

    while((curr = readdir(dd))!=NULL){

        if((strcmp(curr->d_name,".")==0 || strcmp(curr->d_name,"..")==0) && curr->d_type==DT_DIR){

            continue;

        }

        int status = -1;
        int pid = fork();

        if(pid==0){

            //child process
            if(curr->d_type==DT_DIR){

                printf("DIRECTORY:\t%s\n", curr->d_name);
                char new_path[strlen(curr->d_name)+strlen(name)+2];
                sprintf(new_path,"%s/%s",name,curr->d_name);
                //recurse, iterate sub directory
                iterate_dir(new_path);
                _exit(getpid());


            }else{

                printf("FILE:\t%s\n", curr->d_name);
                //sort the file
                _exit(getpid());

            }


        }

        wait(&status);

    }

    closedir(dd);

}

данный и начальный каталог, он работает, но меня беспокоит функция ожидания(). Я хотел бы, чтобы код продолжал обход каталога во время выполнения дочерних процессов, и в настоящее время ожидание предотвращает это. Но мне все еще нужно предотвратить детей-зомби. Будет ли использование waitpid() вместо этого позволить мне иметь эту функциональность (т.е. позволить циклу продолжаться через остальную часть каталога, пока выполняется дочерний процесс), могу ли я просто использовать 1 ожидание в основном, что предотвратит превращение всех созданных процессов в зомби , или есть другой подход, который я должен использовать? Это для школьного проекта, и мне нужно использовать fork (не exec) для создания нового процесса для обхода подкаталогов и нового процесса для сортировки каждого файла.


person Devin M    schedule 11.10.2018    source источник


Ответы (2)


Нет, переход на waitpid() не решит проблему, так как он все равно приостановит цикл до выхода дочернего элемента.

Выньте wait() из основного цикла и сделайте это в конце:

while (wait() > 0) {
}

wait() будет ждать любых дочерних процессов и вернет -1, если дочерних процессов нет.

person Barmar    schedule 11.10.2018

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

Итак, wait() — хороший выбор, так как вы хотите, чтобы каждый процесс ждал завершения дочернего процесса перед запуском нового дочернего процесса или завершением его выполнения.

В другом случае, когда вы хотите, чтобы разные дочерние процессы выполнялись одновременно, вы можете использовать waitpid(-1, &status, WNOHANG), который будет (не) ждать завершения дочернего процесса, то есть он не будет зависать, если ни один дочерний процесс не завершился, но это предотвратит любой законченный дочерний процесс от превращения в зомби.

person UaT    schedule 11.10.2018