Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.97/29: Рейтинг темы: голосов - 29, средняя оценка - 4.97
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052

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

13.03.2018, 10:38. Показов 5702. Ответов 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
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
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
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
13.03.2018, 11:41  [ТС]
Цитата Сообщение от Pavel_Srgv Посмотреть сообщение
resultOfArr у каждого процесса свой после fork'а
А вот этого я не знал. И как решить эту проблему?
0
Заблокирован
13.03.2018, 11:43
Цитата Сообщение от anapshy Посмотреть сообщение
А вот этого я не знал. И как решить эту проблему?
Такая проблема решается методами межпроцессного взаимодействия. Есть много вариантов, можешь загуглить по фразе linux interprocess communication. В твоем случае, например, я бы взял shared memory. А так, на вкус и цвет, как говорится.
1
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
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,922
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
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
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
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru