Аватар для anapshy
533 / 274 / 220
Регистрация: 14.11.2016
Сообщений: 1,054

Нужно дождаться завершения дочернего процесса

13.03.2018, 10:38. Показов 5714. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Суть в том, что нужно обработать каждый массив в новом процессе.
Обработкой занимается ф-я Work().
Понимаю что при создании нового процесса он начинает выполнять тот же код, с момента запуска процесса.
Но как дождаться завершения (чекайте main)? Код выполняет, но Max I & Max II == 0 (это типа Максимальная сумма нечетных(pair->x) и четных(pair->y) ). Я так понял что родительский процесс завершается раньше, чем дочерние. И тупо не успевает записаться информация сумм четных и нечетных в resultOfArr. Как-то надо фиксануть Пробовал wait/waitpid расставлять, где только не пробовал - прогресса 0.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
 
#define MAX_RANDOM 100
#define MAX_ROWS 5
#define MAX_COLS 9999
 
 
struct Pair
{
    int x;
    int y;
};
 
int Random(int value)
{
    return rand() % (value + 1);
}
 
void Fill(int matrix[][MAX_COLS])
{
    int i, j;
    for (i = 0; i < MAX_ROWS; ++i)
    {
        for (j = 0; j < MAX_COLS; ++j)
        {
            matrix[i][j] = Random(MAX_RANDOM);
        }
    }
}
 
void foo(int arr[MAX_COLS], struct Pair *pair)
{
    int i;
    pair->x = 0;
    pair->y = MAX_RANDOM;
    for (i = 0; i < MAX_COLS; ++i)
    {
        if (arr[i] % 2)
        {
            pair->x += arr[i];
        }
        else
        {
            pair->y += arr[i];
        }
    }
}
 
void Work(int arr[MAX_COLS], struct Pair *pair)
{
    foo(arr, pair);
    printf("I: %i\tII: %i\n", pair->x, pair->y);
}
 
struct Pair* FindMaxFromX(struct Pair p_arr[MAX_ROWS])
{
    struct Pair *res = p_arr;
    int i;
    for (i = 1; i < MAX_ROWS; ++i)
    {
        if (p_arr[i].x > res->x)
        {
            res = &p_arr[i];
        }
    }
    return res;
}
 
struct Pair* FindMaxFromY(struct Pair p_arr[MAX_ROWS])
{
    struct Pair *res = p_arr;
    int i;
    for (i = 1; i < MAX_ROWS; ++i)
    {
        if (p_arr[i].y > res->y)
        {
            res = &p_arr[i];
        }
    }
    return res;
}
 
int main(void)
{
    srand((unsigned)time(0));
    int Matrix[MAX_ROWS][MAX_COLS];
    struct Pair resultOfArr[MAX_ROWS];
    Fill(Matrix);
    puts("--------------------");
    {
        int i;
        for (i = 0; i < MAX_ROWS; ++i)
        {
            pid_t pid = fork(); // Создали процесс
            if (pid < 0) // Если не удалось...
            {
                puts("Can't create process!");
                exit(1);
            }
            else if (pid == 0) // Если удалось...
            {
                Work(Matrix[i], &resultOfArr[i]);
                exit(0);
            }
        }
    }
    puts("--------------------");
    printf("Max I: %i\n", FindMaxFromX(resultOfArr)->x);
    printf("Max II: %i\n", FindMaxFromY(resultOfArr)->y);
    puts("--------------------");
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.03.2018, 10:38
Ответы с готовыми решениями:

Составьте UNIX-программу на языке С, порождающую в качестве дочернего процесса свою копию и ожидающую ее завершения
Составьте UNIX-программу на языке С, порождающую в качестве дочернего процесса свою копию и ожидающую ее завершения. Кому не трудно,...

Составьте UNIX-программу на языке С, порождающую в качестве дочернего процесса свою копию и ожидающую ее завершения
Помогите решить пожалуйста. 1. Составьте UNIX-программу на языке С, порождающую в качестве дочернего процесса свою копию и ожидающую ее...

Результат выполнения дочернего процесса
Есть родительский процесс.Внутри создаю дочерний,который выполняет небольшую программу.Допустим просто выводит на экран какое-нибудь...

12
Заблокирован
13.03.2018, 10:57
Цитата Сообщение от anapshy Посмотреть сообщение
Пробовал wait/waitpid расставлять, где только не пробовал - прогресса 0.
Не знаю, что и где ты пробовал, но всю жизнь работало и до конца жизни работать будет:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
 
int main()
{
    int status;
 
    int child_pid = fork();
    if (child_pid == 0)
    {
        sleep(rand()%10);
        puts("From child, before exit.");
    }
    else
    {
        srand(time(NULL));
        wait(&status);
        printf("Child process exited, status %d.\n", status);
    }
    return 0;
}
0
 Аватар для anapshy
533 / 274 / 220
Регистрация: 14.11.2016
Сообщений: 1,054
13.03.2018, 11:16  [ТС]
Pavel_Srgv, в вашем коде wait сработает в том случае когда не удастся создать процесс, или что?
Просто для примера у себя запустите код без создания процессов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* БЕЗ ПРОЦЕССОВ */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define MAX_RANDOM 100
#define MAX_ROWS 5
#define MAX_COLS 9999
 
 
struct Pair
{
    int x;
    int y;
};
 
int Random(int value)
{
    return rand() % (value + 1);
}
 
void Fill(int matrix[][MAX_COLS])
{
    int i, j;
    for (i = 0; i < MAX_ROWS; ++i)
    {
        for (j = 0; j < MAX_COLS; ++j)
        {
            matrix[i][j] = Random(MAX_RANDOM);
        }
    }
}
 
void foo(int arr[MAX_COLS], struct Pair *pair)
{
    int i;
    pair->x = 0;
    pair->y = MAX_RANDOM;
    for (i = 0; i < MAX_COLS; ++i)
    {
        if (arr[i] % 2)
        {
            pair->x += arr[i];
        }
        else
        {
            pair->y += arr[i];
        }
    }
}
 
void Work(int arr[MAX_COLS], struct Pair *pair)
{
    foo(arr, pair);
    printf("I: %i\tII: %i\n", pair->x, pair->y);
}
 
struct Pair* FindMaxFromX(struct Pair p_arr[MAX_ROWS])
{
    struct Pair *res = p_arr;
    int i;
    for (i = 1; i < MAX_ROWS; ++i)
    {
        if (p_arr[i].x > res->x)
        {
            res = &p_arr[i];
        }
    }
    return res;
}
 
struct Pair* FindMaxFromY(struct Pair p_arr[MAX_ROWS])
{
    struct Pair *res = p_arr;
    int i;
    for (i = 1; i < MAX_ROWS; ++i)
    {
        if (p_arr[i].y > res->y)
        {
            res = &p_arr[i];
        }
    }
    return res;
}
 
int main(void)
{
    srand((unsigned)time(0));
    int Matrix[MAX_ROWS][MAX_COLS];
    struct Pair resultOfArr[MAX_ROWS];
    Fill(Matrix);
    puts("--------------------");
    {
        int i;
        for (i = 0; i < MAX_ROWS; ++i)
        {
            Work(Matrix[i], &resultOfArr[i]);
        }
    }
    puts("--------------------");
    printf("Max I: %i\n", FindMaxFromX(resultOfArr)->x);
    printf("Max II: %i\n", FindMaxFromY(resultOfArr)->y);
    puts("--------------------");
    return 0;
}
Потом код выше где с процессами. И увидите разницу в выводе результатов.
0
Заблокирован
13.03.2018, 11:36
Цитата Сообщение от anapshy Посмотреть сообщение
в вашем коде wait сработает в том случае когда не удастся создать процесс, или что?
В моем случае родительский процесс ждет завершения дочернего.

Добавлено через 4 минуты
Цитата Сообщение от anapshy Посмотреть сообщение
И тупо не успевает записаться информация сумм четных и нечетных в resultOfArr.
А ты можешь показать, где дочерний процесс у тебя в коде отдает информацию родительскому? Я очень бегло глянул на код и не увидел этого. Это два разных процесса, у каждого из них своя память, не забывай об этом. Мне кажется, ты не осознал, что resultOfArr у каждого процесса свой после fork'а.
0
 Аватар для anapshy
533 / 274 / 220
Регистрация: 14.11.2016
Сообщений: 1,054
13.03.2018, 11:41  [ТС]
Цитата Сообщение от Pavel_Srgv Посмотреть сообщение
resultOfArr у каждого процесса свой после fork'а
А вот этого я не знал. И как решить эту проблему?
0
Заблокирован
13.03.2018, 11:43
Цитата Сообщение от anapshy Посмотреть сообщение
А вот этого я не знал. И как решить эту проблему?
Такая проблема решается методами межпроцессного взаимодействия. Есть много вариантов, можешь загуглить по фразе linux interprocess communication. В твоем случае, например, я бы взял shared memory. А так, на вкус и цвет, как говорится.
1
 Аватар для anapshy
533 / 274 / 220
Регистрация: 14.11.2016
Сообщений: 1,054
13.03.2018, 11:54  [ТС]
Pavel_Srgv, странно что в теории к лабе о linux interprocess communication ничего не говорится
И вообще впервые слышу об этом.
0
Заблокирован
13.03.2018, 12:00
Цитата Сообщение от anapshy Посмотреть сообщение
Pavel_Srgv, странно что в теории к лабе о linux interprocess communication ничего не говорится
Я не знаю, что у тебя в лабе, и на что там делается упор. Может, там не нужно, чтобы продительский поток собирал информацию со своих дочерних, а, например, чтобы дочерние просто писали свои резульаты в консоль. Я не знаю, что у тебя стоит за задача.
Цитата Сообщение от anapshy Посмотреть сообщение
И вообще впервые слышу об этом.
Всегда бывает первый раз. Это не отменяет того факта, что два разных процесса - это два разных процесса. И не важно, какие имена переменных в исходном коде.
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,928
13.03.2018, 12:05
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
 
int main(){
  pid_t pid = fork();
  int i;
  if(pid == 0){
    for(i=0;i<10;i++){printf("Child\n"); usleep(100000); }
    return 0;
  }else{
    printf("Wait for child\n");
    waitpid(pid,&i,0);
    printf("OK\n");
    return 0;
  }
}
1
 Аватар для anapshy
533 / 274 / 220
Регистрация: 14.11.2016
Сообщений: 1,054
13.03.2018, 12:06  [ТС]
Pavel_Srgv,
Решить задачу с помощью нескольких процессов. Каждый процесс должен вывести свой
идентификатор и отработать заданное время. Массивы заполняются с помощью функции
random().

Даны 5 массивов (по 9999 элементов в каждом). Требуется определить
максимальную сумму четных и нечетных элементов. Обработка каждого массива
выполняется в отдельном процессе.


В теории говорится только о getpid, getppid, wait, waitpid, fork и приведен след пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* Программа выполняет некоторый цикл работ */
    pid_t pid;
    pid=fork(); //создаётся новый процесс
    if (pid<0){ //если выполняется такое условие, то произошла ошибка при создании дочернего процесса
        printf('Cannot create child process. Exit!!!');
        exit(1); //завершаем программу
    }
    if (pid==0){
        // это только что созданный дочерний процесс
        printf('This is child process. My pid %i\n',getpid() );
        … //выполняются некоторые действия
        exit(0); //завершаем дочерний процес
    }
    /* если ни одно условие не выполнилось это родительский процесс*/
    printf('This is parent process. Pid child process %i\n', pid );
    … //выполняются некоторые действия
    return 0;
};
0
Заблокирован
13.03.2018, 12:22
Лучший ответ Сообщение было отмечено anapshy как решение

Решение

Самое просто для тебя решение, на мой вкус - выдели память под resultOfArr с помощью mmap и MAP_SHARED. Процессы пусть записывают в нее свои результаты. Когда все закончат, родительский найдет максимальные суммы среди четных и нечетных. Почему в теории упустили вопрос взаимодействия процессов - вопрос к авторам.
1
 Аватар для anapshy
533 / 274 / 220
Регистрация: 14.11.2016
Сообщений: 1,054
13.03.2018, 12:30  [ТС]
Pavel_Srgv, а если в куче выделить память под resutOfArr? Или тогда тоже разные адреса будут в процессах?!
0
Заблокирован
13.03.2018, 12:35
Цитата Сообщение от anapshy Посмотреть сообщение
Pavel_Srgv, а если в куче выделить память под resutOfArr? Или тогда тоже разные адреса будут в процессах?!
Адреса виртуальной памяти могут быть одинаковыми. Адреса, в общем-то, значения не имеют, потому что это виртуальная память. После попытки записи в динамическую память - у дочернего процесса будет своя копия этой самой памяти. Почитай про fork copy-on-write. У каждого процесса - своя куча, тебе это должно быть тоже известно.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.03.2018, 12:35
Помогаю со студенческими работами здесь

Ограничение прав дочернего процесса
Здравствуйте. Ситуация: есть программа-сервер на C, которая запускает программы-клиенты (не только бинарники, но и java апплеты и python...

Перенаправление stdin/stdout дочернего процесса
Есть программа, доступа к коду которой нет. Она ожидает данные на stdin и выдает ответ на stdout (циклически). Моя программа должна ее...

Передать несколько чисел из дочернего процесса в родительский
В интернете находится информация только о передаче строк через pipe(). Как передать несколько чисел из дочернего процесса в родительский?...

Псевдотерминал: функция возвращает ID дочернего процесса вместо 0 и 1
Товарищи, столкнулся с такой проблемой. Имеется вот код (нашел как пример вебрадио для распбери). Комментарии автора оставил. А теперь,...

Передача имени файла при создании дочернего процесса
Только начинаю программировать под Linux и не совсем понимаю, как это работает Задача такая: Родительский процесс создает n дочерних...


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

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

Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru