2015-02-16 2 views
1

Я довольно новичок в C, поэтому прошу прощения, если это простой вопрос. Я пишу программу на C, часть которой ниже. Целью общей программы является копирование файла из одного места в другое (файлы передаются как аргументы, причем конечным аргументом является назначение). main(), использует fork() для создания одного дочернего процесса для каждого переданного файла, и мне нужно распечатать имя файла (только входной аргумент) вместе с сообщением, которое может включать PID для каждой попытки копирования после запуска всех дочерних процессов ,Порядок, в котором будут выполняться процессы

Я, очевидно, могу получить и использовать PID, это не проблема, но как я могу получить правильное имя файла/аргумент, привязанный к этому процессу? Метод, который у меня есть сейчас, явно ошибочен; простое повторение каждого аргумента по порядку не будет правильным. Это будет выполняться на Minix 2.0.4, но я не знаю, если это имеет значение.

int 
main(int argc, char *argv[]) 
{ 
    int i, pid, rem, status; 
    int pids[argc]; 
    char cfstatus[]; 

    rem = argc; 

    for(i = 1; i < argc; i++) { 
     if((pids[i] = fork()) < 0) { 
     fprintf(stderr, "Error while forking"); 
     } 
     else if(pids[i] == 0) { 
     if(copyfile(argv[i], argv[argc - 1]) == 1) 
      exit(4); 
     else 
      exit(0); 
     } 
    } 

    i = 0; 

    while(rem > 1) { 
     pid = wait(&status); 
     cfstatus = getcfstatus(status, pid); 
     printf("%-20s: %s", argv[i], cfstatus); 
     rem--; 
     i++; 
    } 
} 
+0

код должен проверить, что argc (по крайней мере) 3, и если этот тест завершился с ошибкой, выведите сообщение об ошибке, указывающее правильный формат, а затем завершите – user3629249

+1

argc, включите счетчик для имени программы (это имя найдено в argv [0])), поэтому код необходимо изменить, чтобы учитывать эти две детали. – user3629249

+0

А, хорошо. Он проверяет количество аргументов и терпит неудачу, если передано слишком мало, но я удалил эту проверку в интересах сохранения фрагмента кода в точке. – vaindil

ответ

1

В настоящее время написано, дочерний процесс, чей PID хранится в pids[i] будет работать на файл с именем по argv[i]. В этом нет никакой неопределенности. i дублируется вместе со всем остальным операцией fork и не изменяется после этого.

Однако, поскольку все дети работают параллельно, они могут полностью в любом порядке. То есть, каждый вызов wait может возвращать любой из PID в массиве (который еще не был возвращен). Итак, что вам нужно сделать в вашем цикле wait, это карта назад из значения pid, возвращаемого wait, его индексу в массиве pids, а затем вы знаете нужный индекс в argv для печати. Для такой программы линейный поиск по массиву, вероятно, достаточно хорош.

+0

Это имеет смысл. Спасибо, я очень благодарен! – vaindil

0

эту строку (кроме 'я' не должен быть 0) имеет несколько проблем

"if(copyfile(argv[i], argv[argc - 1]) == 1)' 

если командная строка: ProgramName srcFile desFile

затем ARGC = 3 затем ARGV [ ARGC-1] = srcFile, который не то, что хотел

является предложить:

'if(copyfile(argv[i], argv[argc]) == 1)' 

, то во избежание условий гонки при записи на выход/desFile

только один процесс может записывать в этот файл в любой момент времени.

так разветвление целый ряд процессов, которые будут писать в тот же файл ошибка

эту строку:

'for(i = 0; i < argc; i++) {' 

необходимо несколько модификаций (среди прочего) избежать попытке скопировать исполняемый файл в desFile и избегаем пытается скопировать desFile себе

предложить:

'for(i = 1; i < (argc-1); i++) {' 
+0

'argv []' 0-indexed, поэтому используйте ваш пример 'argc = 3' и, следовательно,' argv [argc-1] = argv [2] = desFile'. Остальная часть имеет смысл. Спасибо! – vaindil

Смежные вопросы