URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9195
[ Назад ]

Исходное сообщение
"Непонятки с fork"

Отправлено CR , 22-Июл-11 18:54 
Есть простенькая программка

#include<stdio.h>
#include<unistd.h>

int main ()
{
    int i;

    for (i = 0; i < 2; i ++) {
        fork();
        printf ("+");
    }
    return 0;
}

Никак не могу понять, почему выводится 8 плюсов?


Содержание

Сообщения в этом обсуждении
"Непонятки с fork"
Отправлено JohnProfic , 22-Июл-11 19:07 
> Никак не могу понять, почему выводится 8 плюсов?

2^3 = 8


"Непонятки с fork"
Отправлено elvenic , 22-Июл-11 19:11 
>[оверквотинг удален]
> {
>     int i;
>     for (i = 0; i < 2; i
> ++) {
>         fork();
>         printf ("+");
>     }
>     return 0;
> }
> Никак не могу понять, почему выводится 8 плюсов?

Попробуйте вот так и немного подумайте над результатом :)

#include<stdio.h>
#include<unistd.h>

int main ()
{
  int i;

  for (i = 0; i < 2; i ++) {
      fork();
      printf ("+ | i: %d pid: %d ppid: %d\n", i, getpid(), getppid());
  }
  return 0;
}



"Непонятки с fork"
Отправлено elvenic , 22-Июл-11 19:15 
Для тех кому лень, вот что выводится. Подсказка: Сколько имено процессов мы запускаем?

+ | i: 0 pid: 17247 ppid: 22353
+ | i: 0 pid: 17248 ppid: 17247
+ | i: 1 pid: 17247 ppid: 22353
+ | i: 1 pid: 17248 ppid: 17247
+ | i: 1 pid: 17250 ppid: 1
+ | i: 1 pid: 17249 ppid: 1


"Непонятки с fork"
Отправлено elvenic , 22-Июл-11 19:22 
> Для тех кому лень, вот что выводится. Подсказка: Сколько имено процессов мы
> запускаем?
> + | i: 0 pid: 17247 ppid: 22353
> + | i: 0 pid: 17248 ppid: 17247
> + | i: 1 pid: 17247 ppid: 22353
> + | i: 1 pid: 17248 ppid: 17247
> + | i: 1 pid: 17250 ppid: 1
> + | i: 1 pid: 17249 ppid: 1

И, кстати, когда процессы умирают? И кто их убивает?



"Непонятки с fork"
Отправлено AHAHAC , 23-Июл-11 22:36 
> И, кстати, когда процессы умирают? И кто их убивает?

А зачем их убивать, если они умирают. Некрофаг чтоля? :)



"Непонятки с fork"
Отправлено CR , 22-Июл-11 19:24 
> Попробуйте вот так и немного подумайте над результатом :)

В данном случае всё понятно, как и ожидалось 6 плюсов. Но откуда в моём примере берётся 8 плюсов? Какие-то заморочки с буферизацией что ли ?


"Непонятки с fork"
Отправлено CR , 22-Июл-11 19:31 
> Какие-то заморочки с буферизацией что ли ?

Вот так меняю программу

int main ()
{
    int i;

    for (i = 0; i < 2; i ++) {
        fork();
        printf (" i: %d pid: %d ppid: %d\n", i, getpid(), getppid());
        printf ("+");
    }
    return 0;
}

вот, что выводит

i: 0 pid: 6319 ppid: 4752
i: 0 pid: 6320 ppid: 6319
+ i: 1 pid: 6319 ppid: 4752
++ i: 1 pid: 6320 ppid: 6319
++ i: 1 pid: 6322 ppid: 1
++ i: 1 pid: 6321 ppid: 1
+


"Непонятки с fork"
Отправлено elvenic , 22-Июл-11 20:13 
>> Попробуйте вот так и немного подумайте над результатом :)
> В данном случае всё понятно, как и ожидалось 6 плюсов. Но откуда
> в моём примере берётся 8 плюсов? Какие-то заморочки с буферизацией что
> ли ?

Да, вы правы, это сложнее чем мне казалось вначале.

И наверно это действительно можно обьяснить буферизацией. Когда потомок форкается, он наследует буфер вывода от родителя, при этом буфер копируется потомку при попытке потомка вывести новый '+'. Теперь есть два буфера, один у родителя, второй у потомка, оба содержат '++'. Ваш первый вариант не выводил '\n' явно, поэтому все буфера выводились в конце работы процесса. Так все потомки, даже те которые по коду программы должны были вывести только один '+', фактически выводили два, из скопированного от родителя буфера вывода.  


"Непонятки с fork"
Отправлено CR , 22-Июл-11 20:31 
Немножко поэкпериментровал. Если написать

printf ("+");
fflush(stdout);

или

write(fileno(stdout), "+", 1);

то выподится 6 плюсов, как и должно быть. Да, буферизация в printf приводит к таким непредвиденным результатам. Будте внимательны, коллеги :-)


"Непонятки с fork"
Отправлено AHAHAC , 23-Июл-11 22:51 
> Немножко поэкпериментровал. Если написать
> printf ("+");
> fflush(stdout);
> или
> write(fileno(stdout), "+", 1);
> то выподится 6 плюсов, как и должно быть. Да, буферизация в printf
> приводит к таким непредвиденным результатам. Будте внимательны, коллеги :-)


#include <stdio.h>
#include <unistd.h>

int main()
{
        int i;

        setbuf(stdout, NULL);

        for (i = 0; i < 2; i++) {
                fork();
                printf("+");
        }
return 0;
}

И ваще


int main() { return write(1, "++++++", 6); }