2009-09-22 3 views
1

я нашел примеры того, как раскошелиться несколько детей, имея что-то вроде этого:Вилка Произвольное количество детей от родителя в C?

if (fork() = 0) { 
    //In child 
} else { 
    if (fork() = 0) { 
     //in second child 

Но если я не знаю, сколько детей я буду нуждаться, как я мог бы сделать это?

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

+0

Итак, вы выполняете присвоение магистерской программы? – BobbyShaftoe

+0

BobbyShaftoe: Я думаю, просто делаю это для себя, я был музыкальным майором ;-) –

ответ

5

Принимая вас на слове, что вам нужно сделать, это для связанного списка:

linked_list_of_commands_t *node = root; 
while (node != NULL) { 
    int pid = fork(); 
    if (pid == -1) { 
     break; // handle error 
    } else if (pid == 0) { 
     // child 
     execv(node->command, node->argv); 
     exit(1); // execv should not return, but just in case the execv call fails 
    } else { 
     node = node->next; 
    } 
} 

Это запустит отдельный процесс для каждого элемента в списке.

+0

Это хороший ответ. Стоит отметить, что в системах POSIX errno устанавливается после сбоя одной из функций exec *. – BobbyShaftoe

+0

@BobbyShaftoe: да, вы можете сообщить об ошибке - но сам факт, что функция exec-family возвращает, означает, что он сработал. –

1

Но количество подпрограмм должно быть исправлено, даже если выполнение по этим ветвям не ограничено. Итак, как насчет цикла while с какой-то логикой оператора switch для каждой процедуры?

+0

Не совсем следуйте, может быть, если вы разместите небольшой код ... –

+0

Я отправил ответ (поставляется с циклом, а не while), содержащий скелетный код – DVK

+0

Другие сообщения имеют хорошие примеры. Но когда я говорю «switch», я имею в виду то, что представляется несколькими вариантами исполнения. Простой цикл, как они показывают, может запускать одну кодированную процедуру много раз (раздвоенный), но вам, похоже, нужны несколько процедур (первая и вторая и т. Д.). Ключ коммутатора (но не обязательно ключевое слово) предназначен для некоторых критериев принятия решений, для которых запускается программа (первая или вторая или так далее). Вы не знаете, как много вы хотите запускать, но параметры/options/не могут быть бесконечными, не так ли? –

1

Как насчет

for (i=0; i< 1000; i++) { 
    pid = fork(); 
    if (pid) { 
     // Error handling for pid==-1 
     break; 
    } 
    // Some logic dependent on value of 'i' 
} 
+0

Итак, я буду отличаться для каждого ребенка? –

+0

Правильно - первый ребенок будет разветвлен, когда i == 0, второй будет разветвлен с i == 1 и т. Д., Поэтому, если ваши команды находятся в массиве «char *», вы можете просто выполнить команды exec как «command_array [i] " – DVK

1
for(i = 0; i < num_children_to_spawn(); ++i) { 
    pid_t pid = fork(); 
    if (pid == -1) { 
     exit(-1); /* error */ 
    } else if (pid == 0) { 
     /* child */ 
     do_child_things(); 
     break; 
    } else { 
     /* parent */ 
    } 
} 

Обратите внимание, что я не использовал переключатель(), потому что это сделало бы его более громоздким break из петли.

+0

' break'? вы вообще не хотите 'exit()' в конце блока дочернего кода? – mob

1
pid_t children_pids[MAX_CHILDREN]; 
int last_child_index = 0; 
for (int i=0; i < num_wanted_children; i++) { 
    pid_t pid = fork(); 
    if (pid == 0) 
    // in child 
    else 
    children_pids[last_child_index++] = pid; 
} 
Смежные вопросы