Во-первых, if
в цикле for ведет себя не так, как вы этого хотите. Помните, что после разветвления он возвращает дочерний PID в родительском процессе и 0 в дочернем. Таким образом, внутри цикла первая ветвь присваивает значение child_1_pid в родительском элементе и переходит ко второму предложению. Дочерний элемент не вводит if
, но продолжает следующую итерацию цикла for. То же самое происходит со вторым пунктом. Таким образом, только основной процесс должен когда-либо входить в тело if
, но не дочерний процесс. Интересно, почему вывод говорит об обратном.
Итак, чтобы получить ваше «двоичное дерево», вы должны иметь следующее:
// COMPLETELY UNTESTED
for(i = 0; i < num_levels; i++){
if (!(child_1_pid = fork()) || !(child_2_pid = fork())) {
printf("\n%d\t%d\t%d\t%d\t%d", i, getpid(), getppid(), child_1_pid, child_2_pid);
// A child process, go on to next iteration.
continue;
}
// A parent process. Wait for children, then stop.
if (child_1_pid) wait();
if (child_2_pid) wait();
break;
}
Странный вывод баннеров связан со сбросом потоков. Обычно fprintf сбрасывается только на символе новой строки (\n
), IIRC. Таким образом, в буфере все еще есть содержимое после разветвления, которое еще не было очищено, и каждый дочерний элемент запускает printf("\n");
и таким образом очищает содержимое буфера.
Решение состоит в том, чтобы добавить «\ n» в конец самого первого printf или вызвать fflush(stdout);
перед циклом for
.