2009-08-06 1 views
3

У меня есть файл C, который выглядит следующим образом:Контроллинг вилы в C

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
int main() 
{ 
    pid_t child_pid; 
    printf ("The PID is %d\n", (int) getpid()); 
    child_pid = fork(); 
    if (child_pid != 0) 
    { 
     printf ("this is the parent process, with PID %d\n", 
     (int)getpid()); 
     printf ("the child's PID is %d\n", (int) child_pid); 
    } 
    else 
     printf ("this is the child process, with PID %d\n", 
     (int)getpid()); 
    return 0; 
} 

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

parent (0) 
    | 
    +---> child (1) 
    | 
    +---> child (2) 
      | 
      +----> child (3) 
      | 
      +----> child (4) 
        | 
        +----> child (5) 
        | 

В основном древовидную структуру, где каждый второй ребенок делает двух новых детей. Насколько я понимаю, когда процессобрабатывается, каждый процесс будет запускаться одновременно. Добавление fork() в операторе if, похоже, работает и корректно создает процессы с 0 по 2, поскольку только родитель создаст новую вилку. Но я понятия не имею, как сделать процесс 2 вилкой, а не 1. Любые идеи?

+1

Считаете ли вы пределы этого процесса? Когда он остановится и почему? Что он будет делать с ОС? (В производной системе unix подумайте о том, чтобы прочитать man-страницу для 'ulimit'.) Просто пытаюсь помочь. – dmckee

ответ

2

Ну, процесс 1 будет создан первой вилкой. Процесс 2 будет создан fork внутри if-statement. Таким образом, чтобы процесс 2 вилки тоже, вы вилка снова внутри условного оператора, если вторая вилка не возвращать 0.

Иллюстрация:

if(fork) { 
    // Inside process 0 
    if(fork) { 
     // still in process 0 
    } else { 
     // in process 2 
     if(fork) { 
      // still in process 2 
     } else { 
      // in prcess 3 
     } 
     // and so on 
    } 
} else { 
    // Inside process 1 
} 
+0

Спасибо. Это делает концепцию более понятной. – pypmannetjies

2

Дети получают копию состояния родителя в то время вилки.

Итак, если у родителя есть счетчик или другое свойство, тогда дети будут видеть значение во время разворота (но не если впоследствии его родитель изменяет).

2

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

Обратите внимание, что fork() - относительно дорогостоящая операция, особенно если вы хотите создать много процессов. Доступны более легкие альтернативы vfork и потоки, но я не могу судить, соответствуют ли они вашим потребностям.

+0

Любой процесс может развиваться, даже дети. Фактически, это то, как пишутся бомбы-вилки, причем каждый процесс разыгрывает еще два, пока система не завалится. – paxdiablo

+0

Thanks pax; Я обновил свой ответ соответственно – Adriaan

+0

Это было просто упражнение - я бы никогда не охотно делал что-то настолько странное :) – pypmannetjies

1

Старый вопрос, но интересный еще. man page для fork() говорит нам, что возвращаемое значение:

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

Итак, мы знаем, что fork() возвращает 0 для ребенка, мы можем использовать это в качестве механизма управления:

int main() 
{ 
    // Here we're in the parent (0) process 

    if(fork()) // This starts the chain, only the parent will do this 
    if(!fork()) //the child will pass this, the parent will skip it 
    for(count = 0; counter < number_of_processes; counter++) //now the 2nd child loops 
    { 
     if(fork()) 
      if(!fork()); 
     else 
      break; 
    } 

Давайте поместим некоторые цифры к нему:

//parent (18402) 
if(fork()) // spawns 18403, parent 18402 keeps going 
    if(!fork()) // spawns 18404, parent 18402 drops to the end of main() 
    for(count = 0; count < number_of_processes; conter++) // 18404 enters here 
     if(fork()) // 18404 forks 18405 and then goes on 
     if(!fork()); // 18404 spawns 18406 before leaving, 18406 restarts the loop 
     else 
      break; // 18404 breaks out there 
     else 
      break; //18405 leaves the loop here 

Таким образом, после одна итерация у нас есть:

18402 
    | 
    +---> 18403 
    | 
    +---> 18404 
      | 
      +----> 18405 
      | 
      +----> 18406 
        | 

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