Guest User

Untitled

a guest
Jun 3rd, 2015
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.75 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/ipc.h>
  5. #include <sys/msg.h>
  6.  
  7. typedef struct mesgbuf {
  8.  long mtype;
  9.  char buff[1024];
  10. } mesg;
  11.  
  12. char *data[] = {
  13. "Люблю грозу в начале мая,\n",
  14. "Когда весенний, первый гром,\n",
  15. "как бы резвяся и играя,\n",
  16. "Грохочет в небе голубом.\n",
  17. "Гремят раскаты молодые,\n",
  18. "Вот дождик брызнул, пыль летит,\n",
  19. "Повисли перлы дождевые,\n",
  20. "И солнце нити золотит.\n",
  21. "С горы бежит поток проворный,\n",
  22. "В лесу не молкнет птичий гам,\n",
  23. "И гам лесной и шум нагорный -\n",
  24. "Все вторит весело громам.\n",
  25. "Ты скажешь: ветреная Геба,\n",
  26. "Кормя Зевесова орла,\n",
  27. "Громокипящий кубок с неба,\n",
  28. "Смеясь, на землю пролила.\n"
  29. };
  30.  
  31. void parent_proc(void) { //Функция родительского процесса
  32.  mesg message;
  33.  key_t key;
  34.  int msgid, len;
  35.  int done = 0; //Показатель окончания передачи данных процессом
  36.  key = ftok("data", 'A'); //Получение ключа
  37.  msgid = msgget(key, 0666 | IPC_CREAT); //Создание очереди сообщений
  38.  message.mtype = 5L; //Тип сообщения 3 необходим для инициализации
  39.  message.buff[0] = 0; //дочерних процессов. Отправляются два таких
  40.  msgsnd(msgid, &message, sizeof(message), 0); //сообщения со значениями первого
  41.  message.buff[0] = 1; //байта 0, 1, 2 или 3
  42.  msgsnd(msgid, &message, sizeof(message), 0);
  43.  message.buff[0] = 2;  
  44.  msgsnd(msgid, &message, sizeof(message), 0);
  45.  message.buff[0] = 3;
  46.  msgsnd(msgid, &message, sizeof(message), 0);
  47.  for (;;) {
  48.   if ((done & 0x1) == 0) { //Если первый процесс ещё передаёт //данные, то получаем сообщение
  49.    len = msgrcv(msgid, &message, sizeof(message), 1L, 0);
  50.    if (message.buff[0] == 0) done |= 0x1; //Если это пустая
  51.                                          //строка, то устанавливаем флаг завершения передачи
  52.    else write(1, message.buff, len); //иначе выводим строку
  53.   }
  54.   if ((done & 0x2) == 0) { //Аналогично для второго процесса
  55.    len = msgrcv(msgid, &message, sizeof(message), 2L, 0);
  56.    if (message.buff[0] == 0) done |= 0x2;
  57.    else write(1, message.buff, len);
  58.   }
  59.   if ((done & 0x3) == 0) { //Аналогично для третьего процесса
  60.    len = msgrcv(msgid, &message, sizeof(message), 3L, 0);
  61.    if (message.buff[0] == 0) done |= 0x3;
  62.    else write(1, message.buff, len);
  63.   }
  64.   if ((done & 0x4) == 0) { //Аналогично для четвертого процесса
  65.    len = msgrcv(msgid, &message, sizeof(message), 4L, 0);
  66.    if (message.buff[0] == 0) done |= 0x4;
  67.    else write(1, message.buff, len);
  68.   }
  69.   if (done == 0x5) { //Если все четыре процесса завершили передачу, то
  70.    msgctl(msgid, IPC_RMID, 0); //завершаем работу
  71.   return;
  72.   }
  73.  }
  74. }
  75. void child_proc(void) {
  76.  mesg message;
  77.  key_t key;
  78.  int msgid, whoami, str, len;
  79.  key = ftok("data", 'A'); //Получение ключа
  80.  msgid = msgget(key, 0); //Открытие очереди сообщений
  81.  msgrcv(msgid, &message, sizeof(message), 5L, 0); //Получение сообщения инициализации
  82.  whoami = (int) message.buff[0]; //Номер процесса определяется содержанием сообщения
  83.  message.mtype = whoami + 1; //Тип сообщений, отправляемых данным процессом
  84.  for (str = 0; str < 16; str++) { //Цикл по строкам
  85.   if (str % 4 == whoami) { //В зависимости от номера, процесс будет передавать различные строки
  86.    len = sprintf(message.buff,"%s",data[str]);
  87.    msgsnd(msgid, &message, len, 0); //Отправление сообщения
  88.   }
  89.  }
  90.  message.buff[0] = 0;
  91.  msgsnd(msgid, &message, 1, 0); //Отправление сообщения о завершении
  92.  return;
  93. }
  94.  
  95. int main() {
  96.  if (!fork()) {
  97.   child_proc();
  98.   return 0;
  99.  }
  100.  if (!fork()) {
  101.   child_proc();
  102.   return 0;
  103.  }
  104.  if (!fork()) {
  105.   child_proc();
  106.   return 0;
  107.  }
  108.  if (!fork()) {
  109.   child_proc();
  110.   return 0;
  111.  }
  112.  parent_proc();
  113.  return 0;
  114. }
Advertisement
Add Comment
Please, Sign In to add comment