Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
0 / 0 / 0
Регистрация: 19.10.2014
Сообщений: 5

Родительские и дочерние процессы

03.06.2015, 16:53. Показов 3019. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Что-то никогда не думал, что буду спрашивать у кого-то, как делать лабы, сам справлялся(до этого без проблем писал самостоятельно лабораторные и не только на java), но что-то вот это задание для меня слишком сложное, а точнее, я просто не понимаю, где может быть ошибка.
Итак: есть лаба сделанная одногруппником, нужно всего лишь переделать ее под мое условие, казалось бы, чего проще, но что-то не так
Задание одногруппника:
Кликните здесь для просмотра всего текста
Два дочерних процесса выполняют некоторые циклы работ, передавая после окончания очередного цикла через очередь сообщений родительскому процессу очередные четыре строки некоторого стихотворения, при этом первый процесс передает нечетные четырехстишья, второй - четные. Циклы работ процессов не сбалансированы по времени. Родительский процесс компонует из передаваемых фрагментов законченное стихотворение и выводит его по завершении работы обоих процессов.

Код одногруппника:
Кликните здесь для просмотра всего текста
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
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
 
typedef struct mesgbuf {
long mtype;
char buff[1024];
} mesg;
 
char *data[] = {
"Гой ты, Русь, моя родная,\n\
Хаты - в ризах образа...\n\
Не видать конца и края -\n\
Только синь сосет глаза.\n\n",
 
"Как захожий богомолец,\n\
Я смотрю твои поля.\n\
А у низеньких околиц\n\
Звонно чахнут тополя.\n\n",
 
"Пахнет яблоком и медом\n\
По церквам твой кроткий Спас.\n\
И гудит за корогодом\n\
На лугах веселый пляс.\n\n",
 
"Побегу по мятой стежке\n\
На приволь зеленых лех,\n\
Мне навстречу, как сережки,\n\
Прозвенит девичий смех.\n\n",
 
"Если крикнет рать святая:\n\
Кинь ты Русь, живи в раю!\n\
Я скажу: Не надо рая,\n\
Дайте родину мою.\n"
};
 
void parent_proc(void) { //Функция родительского процесса
mesg message;
key_t key;
int msgid, len;
int done = 0; //Показатель окончания передачи данных процессом
key = ftok("data", 'A'); //Получение ключа
msgid = msgget(key, 0666 | IPC_CREAT); //Создание очереди сообщений
message.mtype = 3L; //Тип сообщения 3 необходим для инициализации
message.buff[0] = 0; //дочерних процессов. Отправляются два таких
msgsnd(msgid, &message, sizeof(message), 0); //сообщения со значениями первого
message.buff[0] = 1; //байта 0 и 1
msgsnd(msgid, &message, sizeof(message), 0);
for (;;) {
  if ((done & 0x1) == 0) { //Если первый процесс ещё передаёт //данные, то получаем сообщение
   len = msgrcv(msgid, &message, sizeof(message), 1L, 0);
   if (message.buff[0] == 0) done |= 0x1; //Если это пустая
                                                                                 //строка, то устанавливаем флаг завершения передачи
   else write(1, message.buff, len); //иначе выводим строку
  }
  if ((done & 0x2) == 0) { //Аналогично для второго процесса
   len = msgrcv(msgid, &message, sizeof(message), 2L, 0);
   if (message.buff[0] == 0) done |= 0x2;
   else write(1, message.buff, len);
  }
  if (done == 0x3) { //Если оба процесса завершили передачу, то
   msgctl(msgid, IPC_RMID, 0); //завершаем работу
  return;
  }
}
}
void child_proc(void) {
mesg message;
key_t key;
int msgid, whoami, str, len;
key = ftok("data", 'A'); //Получение ключа
msgid = msgget(key, 0); //Открытие очереди сообщений
msgrcv(msgid, &message, sizeof(message), 3L, 0); //Получение сообщения инициализации
whoami = (int) message.buff[0]; //Номер процесса определяется содержанием сообщения
message.mtype = whoami + 1; //Тип сообщений, отправляемых данным процессом
for (str = 0; str < 5; str++) { //Цикл по четверостишиям
  if (str % 2 == whoami) { //В зависимости от номера, процесс будет передавать чётные или нечётные четверостишия
   len = sprintf(message.buff,"%s",data[str]);
   msgsnd(msgid, &message, len, 0); //Отправление сообщения
  }
}
message.buff[0] = 0;
msgsnd(msgid, &message, 1, 0); //Отправление сообщения о завершении
return;
}
 
int main() {
if (!fork()) {
  child_proc();
  return 0;
}
if (!fork()) {
  child_proc();
  return 0;
}
parent_proc();
return 0;
}

Мое задание:
Кликните здесь для просмотра всего текста
Четыре дочерних процесса выполняют некоторые циклы работ, передавая после окончания очередного цикла через один и тот же сегмент разделяемой памяти родительскому процессу очередную строку некоторого стихотворения, при этом первый процесс передает 1-ю, 5-ю, 9-ю и т.д. строки, второй - 2-ю, 6-ю, 10-ю и т.д. строки, третий - 3-ю, 7-ю, 11-ю и т.д. строки, четвертый - 4-ю, 8-ю, 12-ю и т.д. строки. Циклы работ процессов не сбалансированы по времени. Родительский процесс компонует из передаваемых фрагментов законченное стихотворение и выводит его по завершении работы всех процессов

Мой код
Кликните здесь для просмотра всего текста
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
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
 
typedef struct mesgbuf {
long mtype;
char buff[1024];
} mesg;
 
char *data[] = {
"Люблю грозу в начале мая,\n",
"Когда весенний, первый гром,\n",
"как бы резвяся и играя,\n",
"Грохочет в небе голубом.\n",
"Гремят раскаты молодые,\n",
"Вот дождик брызнул, пыль летит,\n",
"Повисли перлы дождевые,\n",
"И солнце нити золотит.\n",
"С горы бежит поток проворный,\n",
"В лесу не молкнет птичий гам,\n",
"И гам лесной и шум нагорный -\n",
"Все вторит весело громам.\n",
"Ты скажешь: ветреная Геба,\n",
"Кормя Зевесова орла,\n",
"Громокипящий кубок с неба,\n",
"Смеясь, на землю пролила.\n"
};
 
void parent_proc(void) { //Функция родительского процесса
mesg message;
key_t key;
int msgid, len;
int done = 0; //Показатель окончания передачи данных процессом
key = ftok("data", 'A'); //Получение ключа
msgid = msgget(key, 0666 | IPC_CREAT); //Создание очереди сообщений
message.mtype = 5L; //Тип сообщения 3 необходим для инициализации
message.buff[0] = 0; //дочерних процессов. Отправляются два таких
msgsnd(msgid, &message, sizeof(message), 0); //сообщения со значениями первого
message.buff[0] = 1; //байта 0, 1, 2 или 3
msgsnd(msgid, &message, sizeof(message), 0);
message.buff[0] = 2;  
msgsnd(msgid, &message, sizeof(message), 0);
message.buff[0] = 3;
msgsnd(msgid, &message, sizeof(message), 0);
for (;;) {
  if ((done & 0x1) == 0) { //Если первый процесс ещё передаёт //данные, то получаем сообщение
   len = msgrcv(msgid, &message, sizeof(message), 1L, 0);
   if (message.buff[0] == 0) done |= 0x1; //Если это пустая
                                                                                 //строка, то устанавливаем флаг завершения передачи
   else write(1, message.buff, len); //иначе выводим строку
  }
  if ((done & 0x2) == 0) { //Аналогично для второго процесса
   len = msgrcv(msgid, &message, sizeof(message), 2L, 0);
   if (message.buff[0] == 0) done |= 0x2;
   else write(1, message.buff, len);
  }
  if ((done & 0x3) == 0) { //Аналогично для третьего процесса
   len = msgrcv(msgid, &message, sizeof(message), 3L, 0);
   if (message.buff[0] == 0) done |= 0x3;
   else write(1, message.buff, len);
  }
  if ((done & 0x4) == 0) { //Аналогично для четвертого процесса
   len = msgrcv(msgid, &message, sizeof(message), 4L, 0);
   if (message.buff[0] == 0) done |= 0x4;
   else write(1, message.buff, len);
  }
  if (done == 0x5) { //Если все четыре процесса завершили передачу, то
   msgctl(msgid, IPC_RMID, 0); //завершаем работу
  return;
  }
}
}
void child_proc(void) {
mesg message;
key_t key;
int msgid, whoami, str, len;
key = ftok("data", 'A'); //Получение ключа
msgid = msgget(key, 0); //Открытие очереди сообщений
msgrcv(msgid, &message, sizeof(message), 5L, 0); //Получение сообщения инициализации
whoami = (int) message.buff[0]; //Номер процесса определяется содержанием сообщения
message.mtype = whoami + 1; //Тип сообщений, отправляемых данным процессом
for (str = 0; str < 16; str++) { //Цикл по строкам
  if (str % 4 == whoami) { //В зависимости от номера процесса, процесс будет передавать различные строки
   len = sprintf(message.buff,"%s",data[str]);
   msgsnd(msgid, &message, len, 0); //Отправление сообщения
  }
}
message.buff[0] = 0;
msgsnd(msgid, &message, 1, 0); //Отправление сообщения о завершении
return;
}
 
int main() {
if (!fork()) {
  child_proc();
  return 0;
}
if (!fork()) {
  child_proc();
  return 0;
}
if (!fork()) {
  child_proc();
  return 0;
}
if (!fork()) {
  child_proc();
  return 0;
}
parent_proc();
return 0;
}

Моя программа никогда не завершается нормально, выводятся то одни, то другие строки, и приходится прерывать работу.
Ошибка, судя по всему, или в поле buff структуры, неправильно назначаю (где
Code
1
mesage.buff[0] = ...
), или в функции msgrcv в аргументе msgtyp(предпоследний). Или вообще неправильное понимание того, как эта программа работает (не понимаю, если честно, как эти потоки между собой и с родительским потоком взаимодействуют)
Я прошерстил мануалы к этим функциям, и вроде бы, все должно работать. На мой взгляд... Но не работает
Посмотрите, пожалуйста, может увидите ошибку. Заранее спасибо

Не по теме:

кстати, вроде лаба сделана не прямо по заданию(в задании вообще указывалось, что нужно сделать ее через семафоры), но это неважно



Добавлено через 19 минут
Одна из ошибок найдена: я неправильно проверяю биты (0х3, 0х4 и т.д), но программа все равно не работает
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.06.2015, 16:53
Ответы с готовыми решениями:

Родительские и дочерние процессы
Здравствуйте, форумчане, рад буду любой помощи и полезной информации по ниже приведенному заданию, буду весьма благодарен за любую помощь...

FIFO и дочерние процессы
День добрый, пишу курсач вот задание: вот что я навоял: #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include...

[C] Породить дочерние процессы
Нужно что-бы отцовский процесс породил трех сыновей, а каждый сын печатает свой пид и пид двух других сыновей

2
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
03.06.2015, 19:06
Для простоты дочерние процессы помещают указанные строки сразу в нужное место разделяемого блока памяти, и родительскому остается только вывести результат. Но формально условия задания соблюдены.
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
#include <stdio.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <string.h>
#define SHM_SIZE 100*64
 
main() {
  int i, j;
  int id= shmget (IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
  for (i= 0; i < 4; i++) if (!fork()) break;
 
  char (*data)[64]= shmat (id, 0, 0);
  if (data == (void*)-1) {perror(0); return -1;}
 
  if (i == 4) {
    for (j= 0; j<4; j++) wait(0);
    for (j= 0; data[j] && data[j][0]; j++) printf (data[j]);
  }
  else {
    char buf[100][64];
    FILE *f= fopen ("slovo.txt", "r");
    if (!f) {perror (0); return -1;}
 
    for (j=0; !feof (f); j++) {
      fgets (buf[j], 64, f);
      if ((j % 4) == i) strncpy (data[j], buf[j], 64);
      strncpy (data[j], buf[j], 64);
    }
    if (i == 1) data[j][0]= 0;
    fclose (f);
  }
  shmdt (data);
}
Добавлено через 12 минут
Исправил неточности и убрал лишнее (строки 20-30)
C
1
2
3
4
5
6
7
8
9
10
    char buf[64];
    FILE *f= fopen ("slovo.txt", "r");
    if (!f) {perror (0); return -1;}
 
    for (j=0; !feof (f); j++) {
      fgets (buf, 64, f);
      if ((j % 4) == i) strncpy (data[j], buf, 64);
    }
    if (i == 1) data[j-1][0]= 0;
    fclose (f);
1
0 / 0 / 0
Регистрация: 19.10.2014
Сообщений: 5
03.06.2015, 22:08  [ТС]
Интересное решение. И такое короткое. Спасибо большое, прям огромное даже
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.06.2015, 22:08
Помогаю со студенческими работами здесь

Потоки ввода/вывода, дочерние процессы и FIFO
Доброго времени суток! пишу курсовую, через неделю нужно здать, поэтому прошу помощи, знаю что эта тема уже раннее обсуждалась, но до...

Дочерние процессы должны сгенерировать случайные числа и передать их родителю
помогите решить проблему: В общем есть 6 процессов, 1 родитель и 5 дочерних, дочернии процессы должны с генерировать случайные числа и...

Родительские и дочерние объекты
Работаю над игрой в стиле TDS. У врага есть триггер и в скрипте врага метод private void OnTriggerEnter2D(Collider2D collision) { ...

Родительские и дочерние классы
Всем привет, помогите с задачами: 1) Определить класс Комплекс. Реализовать методы для сложения, вычитания, умножения, деления...

Родительские/дочерние документы
Подскажите, пожалуйста, просто должно быть, только что-то я уже совсем торможу. Есть родительский док. (есть форма), имеет несколько...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru