47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
1

Создается только один потомок и не создаются дополнительные при следующем входе в цикл

24.04.2016, 21:07. Показов 1250. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
 
int main ()
{
  int i;
 
  for (i = 0; i < 2; i ++) {
    fork();
    printf (".");
  }
  return 0;
}
https://ideone.com/FezbDV

Выполнение данного кода печатает 4 точки. Хотя судя из описания этой системной функции должно быть напечатано..
по моим подсчетам 6.. почему создается только один потомок и не создаются дополнительные при следующем входе в цикл?

Добавлено через 1 час 45 минут
т.е. всего будет порождено 3 процесса (общее кол-во процессов = 4)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.04.2016, 21:07
Ответы с готовыми решениями:

Не создаются новые потоки при распараллеливании цикла for (работает только один поток - главный)
Доброго времени суток, ребята! Пишу код по распараллеливанию умножения матриц. Всё вроде...

Функция: есть ли в бинарном дереве внутренний узел, у которого только один потомок?
Здравствуйте. Помогите пожалуйста. Надо написать функцию,проверяющую есть ли в дереве внутренний...

Если внутри функции создается объект с помощью gcnew, он создается один раз или при каждом вызове?
Обработчик по нажатию кнопки Visual C++ 2010 private: System::Void but1_Click(System::Object^...

При нажатии на кнопку файл не создается на диске, а он создается только после сворачивания или закрытия окна...
Знакомлюсь с графическим интерфейсом Java Swing. Появилась такая проблема: при нажатии на кнопку...

7
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
25.04.2016, 19:43 2
Цитата Сообщение от Pink_Pank Посмотреть сообщение
по моим подсчетам 6
Маладэц! Правильно считаете.
Цитата Сообщение от Pink_Pank Посмотреть сообщение
почему создается только один потомок и не создаются дополнительные при следующем входе в цикл?
Откуда вы это взяли. Исправьте ошибки и будет шесть.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
int main ()
{
  int i;
 
  for (i = 0; i < 2; i ++) {
    int pd= fork();
    printf (".\n");
    if (pd) wait (0);
  }
  return 0;
}
1
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
25.04.2016, 19:50  [ТС] 3
А так вообще 8.
https://ideone.com/SZCVzg

А Вы хотите сказать, что у меня родительский поток завершается раньше дочерних и останавливает их работу?.. Почему он должен их останавливать? Или как это объяснить. и откуда в Вашем примере взялось 8 точек?
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
25.04.2016, 20:04 4
Цитата Сообщение от Pink_Pank Посмотреть сообщение
А Вы хотите сказать, что у меня родительский поток завершается раньше дочерних и останавливает их работу?
Я ничего не хочу сказать, но такая ситуация обязана быть предусмотренной.
Цитата Сообщение от Pink_Pank Посмотреть сообщение
Почему он должен их останавливать?
Должен, если успеет.
Цитата Сообщение от Pink_Pank Посмотреть сообщение
откуда в Вашем примере взялось 8 точек?
У меня их шесть. Почему восемь на вашем сайте - наверное, потому что printf не является процессо- независимой. Распечатайте пиды и посмотрите.
1
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
26.04.2016, 12:03  [ТС] 5
Цитата Сообщение от gng Посмотреть сообщение
Должен, если успеет.
Прошу прощения, что без ссылок. Недавно просмотрел множество ресурсов по этой теме.
Прочитал следующее (своими словами):
если дочерний поток завершается раньше родительского, то он возвращает родительскому результат своего выполнения. и висит в записях запущенных процессов ОС (зомби) до тех пор, пока родитель не обработает этот возврат или пока родитель не завершится.
А если родитель завершается вперед дочернего, то все порожденные им процессы наследуются системным потоком Init (ну, или как-то так он называется, который стартует при запуске ОС и порождает все остальные процессы) с PID = 1. И результат возврата из дочерних процессов обрабатывает уже этот Init.
А вот чтобы завершать дочерние процессы при завершении родительского - так когда такая необходимость появляется, люди (судя по форумам) еще и пытаются извернуться, чтобы эту ситуацию воплотить в реальность. Т.е. по умолчанию в ОС Unix этого не предусмотрено.
Цитата Сообщение от gng Посмотреть сообщение
Почему восемь на вашем сайте - наверное, потому что printf не является процессо- независимой. Распечатайте пиды и посмотрите.
Я могу предположить только, что порожденные процессы (3 процесса) продолжили выполнение не с момента вызова fork(), а с самого начала, что совсем не поддается никакому объяснению. Сейчас попробую скомпилить и запустить под Убунтой на виртуалке.
А по поводу printf, насколько помню, там внутри нее выделяется свой буфер и каждый процесс, который к ней обращается, добавляет в этот буфер символы для печати. а те уже, в свою очередь, печатаются по мере возможности.

Добавлено через 23 минуты
В Убунту также 8 точек и всего 4 процесса (1 родитель и 3 дочи)
Т.е. все они выполняются (по крайней мере цикл выполняется) полностью. Странно.. почему они не продолжают с места вызова fork()..
Немного модифицировал код. Да, выполняется полностью именно с момента начала цикла.. Странно..
Кто-то знает, почему игнорируется текущее значение локальных переменных цикла и тот запускается с начала?
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
26.04.2016, 12:13 6
Цитата Сообщение от Pink_Pank Посмотреть сообщение
В Убунту также 8 точек и всего 4 процесса (1 родитель и 3 дочи)
Т.е. все они выполняются (по крайней мере цикл выполняется) полностью. Странно.. почему они не продолжают с места вызова fork()..
У меня шесть
Bash
1
2
3
4
5
gg@:~/cc/tmp$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
gg@:~/cc/tmp$ uname -a
Linux 4.2.0-0.bpo.1-amd64 #1 SMP Debian 4.2.6-3~bpo8+2 (2015-12-14) x86_64 GNU/Linux
И должно быть шесть. Проверить просто. Вместо принтфа делайте что-то другое, напр. создавайте отдельный файл.
1
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
26.04.2016, 13:09  [ТС] 7
В общем, если так написать:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int main ()
{
  int i;
 
  for (i = 0; i < 2; i ++) {
    printf("I am process\n");
    int pd= fork();
    printf (".\n");
    if (pd) wait (0);
  }
  printf("the end\n");
  return 0;
}
то работает нормально.
а если закомментить и запустить вот так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int main ()
{
  int i;
 
  for (i = 0; i < 2; i ++) {
    //printf("I am process\n");
    int pd= fork();
    printf (".\n");
    if (pd) wait (0);
  }
  printf("the end\n");
  return 0;
}
то работает через одно место. Видимо, действительно проблема в printf()

А по поводу завершения дочерних процессов при завершении родительского может кто-то ссылок накидать по теме, где бы это подробно разбиралось? Желательно на русском.
Миниатюры
Создается только один потомок и не создаются дополнительные при следующем входе в цикл  
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
26.04.2016, 13:38 8
Лучший ответ Сообщение было отмечено Pink_Pank как решение

Решение

Цитата Сообщение от Pink_Pank Посмотреть сообщение
по поводу завершения дочерних процессов при завершении родительского
Выше вы верно написали. Дочерние переходят к процессу 1 (init или systemd или ...). Тем не менее, если процесс подключен к тому же терминалу, его необходимо ожидать.
Если завершается лидер сессии, то он завершает всё свое дерево.
В общих чертах можно посмотреть https://www.win.tue.nl/~aeb/linux/lk/lk-10.html
1
26.04.2016, 13:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.04.2016, 13:38
Помогаю со студенческими работами здесь

Команда "Требовать смены пароля при следующем входе в систему"
Нужна команда, которая поставит на локальных пользователей флажок &quot;Требовать смены пароля при...

Факториал. Использовать только одну функцию main и только один цикл
задача вообщем простая, но условия осложняют: \sum_{i=0}^{n-1} {x}_{i}/i! использовать только...

Ошибка: "Меню "Пуск" не работает. Мы попытаемся восстановить его при вашем следующем входе в систему"
Ни с того, ни с сего, начала возникать ошибка при нажатии на кнопку пуск:Меню &quot;Пуск&quot; не работает....

Ошибка при входе в цикл по компонентам формы
При входе в цикл по компонентам формы сразу вылетает ошибка (при первом же обороте). Кто-нибудь...

Как в наше время создаются дополнительные страницы сайта?
Друзья, как в 2015 году профессионально создаются 2, 3 и т.д. страницы сайта. Если, например, на...

Цикл выполняется только один раз
var a, b, s :integer; begin read (a); s:=0; repeat begin if (a mod 10 mod 2)&lt;&gt;0 then s:=s + a...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru