0 / 0 / 0
Регистрация: 19.10.2014
Сообщений: 5

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

03.06.2015, 16:53. Показов 3024. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru