The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Непонятки с fork"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Процессы, Треды, RPC)
Изначальное сообщение [ Отслеживать ]

"Непонятки с fork"  +/
Сообщение от CR on 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 плюсов?

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Непонятки с fork"  +/
Сообщение от JohnProfic (ok) on 22-Июл-11, 19:07 
> Никак не могу понять, почему выводится 8 плюсов?

2^3 = 8

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Непонятки с fork"  +/
Сообщение от elvenic (??) on 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;
}


Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "Непонятки с fork"  +/
Сообщение от elvenic (??) on 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

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "Непонятки с fork"  +/
Сообщение от elvenic (??) on 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

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


Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

9. "Непонятки с fork"  +/
Сообщение от AHAHAC (ok) on 23-Июл-11, 22:36 
> И, кстати, когда процессы умирают? И кто их убивает?

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


Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

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

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

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

6. "Непонятки с fork"  +/
Сообщение от CR on 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
+

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

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

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

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

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

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

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

или

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

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

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

10. "Непонятки с fork"  +/
Сообщение от AHAHAC (ok) on 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); }

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру