Управление вилками в C - PullRequest
       21

Управление вилками в C

3 голосов
/ 06 августа 2009

У меня есть файл 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() процесс, каждый процесс будет выполняться одновременно. Кажется, что добавление fork() в оператор if работает и правильно создает процессы с 0 по 2, поскольку только родительский объект создаст новый ответвление. Но я понятия не имею, как сделать процесс 2 форка, а не 1. Есть идеи?

Ответы [ 4 ]

2 голосов
/ 06 августа 2009

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

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

2 голосов
/ 06 августа 2009

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

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

2 голосов
/ 06 августа 2009

Ну, процесс 1 будет создан первым форком. Процесс 2 будет создан форком внутри оператора if. Таким образом, чтобы разрешить процессу 2 форкать, вы снова форкаете внутри оператора if, если второй форк не вернул 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
}
1 голос
/ 03 декабря 2012

Старый вопрос, но все же интересный. Страница man для 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
                     |

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...