Я пытаюсь использовать несколько вызовов fork () для создания нескольких дочерних элементов с разными задачами Я нашел код на Несколько дочерних процессов

Что действительно близко к тому, что я хочу, но я не мог полностью этого понять

pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild != 0)
{
  // In parent
  secondChild = fork();
  if(secondChild != 0)
  {
    // In parent
  }
  else
  {
    // In secondChild
  }
}
else
{
  // In firstChild
}

Мои вопросы:

  • Сколько процессов было создано (я предполагаю, что у нас их 4, так как это 2 вилки!)?
  • В этой части кода
firstChild = fork();
if(firstChild != 0)
{
    // In parent
    secondChild = fork();
    if(secondChild != 0)
    {
        // In parent
    }

Означает ли "// в родительском", что они оба являются одним и тем же процессом (у них одинаковый PID, когда я пытался его протестировать).

  • Как я могу создать 3 дочерних элемента, используя 2 вилки? (Я могу нарисовать дерево, которое заканчивается 4 листьями, 3 из них являются дочерними и 1 родительский)

Спасибо (пожалуйста, сообщите мне, если я не полностью понимаю концепцию вилки)

0
Muhannad 26 Фев 2015 в 12:56

2 ответа

Лучший ответ

Сколько процессов было создано (я предполагаю, что у нас их 4, так как это 2 вилки!)?

В зависимости от результата вашего forks он должен быть от 0 до 2. Возможно 2, если ничего не пойдет не так. Есть родительский процесс, который порождает 2 дочерних процесса.

Означает ли "// в родительском", что они оба являются одним и тем же процессом (у них одинаковый PID, когда я пытался его протестировать).

Да. В вашем случае код проверяет, не является ли возвращаемое значение fork ненулевым. Это не очень хорошая идея, поскольку она охватывает два разных случая:

  • Это может быть меньше нуля, что указывает на ошибку, или ...
  • Он может быть больше нуля, указывая родителю на pid только что порожденного процесса. В любом случае ... учитывая, что все идет хорошо, и обе вилки работают успешно, у вас получится родительский процесс с двумя разными дочерними элементами.

Как я могу создать 3 дочерних элемента, используя 2 вилки? (Я могу нарисовать дерево, которое заканчивается 4 листьями, 3 из них дочерние, а 1 родитель

Что-то вроде этого должно помочь:

firstChild = fork();
if (firstChild < 0) {
    exit(EXIT_FAILURE);
    perror("fork");
}
secondChild = fork();

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

parent─┬─child1───(child1's child)
       └─child2

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

parent─┬─child1
       ├─child3
       └─child2

Примечание. В stackoverflow принято ограничиваться только одним вопросом на тему.

1
dragosht 26 Фев 2015 в 10:22

В следующем коде показано, как создать 4 процесса (1 родительский и 3 дочерних) только с 2 вилками.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int *list;

void calculate_average(int );
void calculate_maximum(int);
void calculate_minimum(int);

void calculate_average(int count) 
{
        int i, total = 0;


        for (i = 0; i < count; i++)
                total += list[i];

        double average = total / count;
        
	printf("average is %f\n",average);

}

void calculate_maximum(int count)
{
        int i;

        int maximum = list[0];

        for (i = 1; i < count; i++)
                if (list[i] > maximum)
                        maximum = list[i];

	printf("maximum is %d\n",maximum);
}

void calculate_minimum(int count)
{
        int i;

        int minimum = list[0];

        for (i = 1; i < count; i++)
                if (list[i] < minimum)
                        minimum = list[i];
	printf("minimum is %d\n",minimum);
}

int main(int argc, char *argv[])
{
	pid_t pid, pid1;

	int num_of_args = argc-1;
	int i;

	/* allocate memory to hold array of integers */
        list = malloc(sizeof(int)*num_of_args);

        for (i = 0; i < num_of_args; i++)
                list[i] = atoi(argv[i+1]);
        
	printf("The %d number of input ingeters are\n",num_of_args);
        for (i = 0; i < num_of_args; i++)
                printf("%d\n",list[i]);

	/* fork a child process */
	pid = fork();

	if (pid < 0) { /* error occurred */
		fprintf(stderr, "Fork Failed\n");
		return 1;
	}
	else if (pid == 0) { /* P2 */
		pid1=getppid();
		calculate_average(num_of_args);
	}

	else { 		/* P1 */
		pid1=getpid();
		wait(NULL);
	}
	
 	pid = fork();
	
	if (pid < 0) { /* error occurred */
		fprintf(stderr, "Fork Failed\n");
		return 1;
	}
	
	else if (pid == 0) { /* could be either P3 or P4 */
		if (getppid() == pid1) { /* P3 */
			calculate_minimum(num_of_args);
		}	

		else {  /* P4 */
			calculate_maximum(num_of_args);
		}
	}
	
	else { 
		wait(NULL);
	}
    
    	return 0;
}

Обратите внимание, что один из детей будет родителем для внука.

0
Muhannad 14 Мар 2015 в 23:16