Использование wait () против waitpid () в c - PullRequest
0 голосов
/ 11 октября 2018

Поэтому я пытаюсь пройти по каталогу (и подкаталогам) и создать новые процессы для сортировки файлов и обхода подкаталогов.Однако у меня возникли небольшие проблемы с пониманием того, насколько полезным будет мой код.Насколько я понимаю, 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);

}

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

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

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

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

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

0 голосов
/ 11 октября 2018

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

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

while (wait() > 0) {
}

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

...