Gistrec

Управление ресурсами в ВЧ 7

May 14th, 2019
418
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.08 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <cassert> /** assert() */
  5.  
  6. #include <sys/ipc.h>
  7. #include <sys/msg.h>
  8. #include <unistd.h>   /** fork() */
  9. #include <sys/wait.h> /** wait() */
  10. #include <sys/sem.h>
  11. #include <string.h>
  12.  
  13. #define CHILD 0
  14.  
  15. using std::vector;
  16. using std::string;
  17.  
  18. vector<string> text = {
  19.         "Ошибается в мире каждый -",
  20.         "И на солнце ведь пятна есть.",
  21.         "Жизнь, как дом, многоэтажный -",
  22.         "Тёмных окон в нём не счесть.",
  23.  
  24.         "Но есть люди, хоть раз споткнувшись,",
  25.         "Прекращают вперёд идти,",
  26.         "От мечты своей отвернувшись,",
  27.         "Вдруг решают уйти с пути.",
  28.  
  29.         "И легко им потом живётся,",
  30.         "Без падений на твёрдый пол,",
  31.         "Белой нитью вся жизнь плетётся,",
  32.         "Составляя один узор."
  33. };
  34.  
  35.  
  36.  
  37. struct msg {
  38.     long    mtype;       /* тип сообщения, должен быть > 0 */
  39.     char    mtext[80];   /* содержание сообщения */
  40.  
  41.     msg(const char *text) {
  42.         mtype = 1;
  43.         strncpy(mtext, text, 80);
  44.     };
  45. };
  46.  
  47. /**
  48.  * Дочерний процесс
  49.  * @param start - номер первой строки для текущего дочернего процесса
  50.  */
  51. void thread(int semid, int msgqid, int start) {
  52.     sembuf buf = { 0 };
  53.  
  54.     for (int i = start; i < 12; i += 4) {
  55.         buf.sem_op = -i; // Для блокировки семафора нужен вес i
  56.         int result = semop(semid, &buf, 1);
  57.         assert(result != -1 && "Error: Can't lock semaphore");
  58.  
  59.         msg msg_obj(text[i].c_str());
  60.  
  61.         std::cout << "Отправили в очередь " << i << " строку" << std::endl;
  62.  
  63.         result = msgsnd(msgqid, &msg_obj, sizeof(msg_obj), IPC_NOWAIT);
  64.         assert(result != -1 && "Error: Can't send message to IPC");
  65.  
  66.         buf.sem_op = i + 1;
  67.         result = semop(semid, &buf, 1);
  68.         assert(result != -1 && "Error: Can't increment semaphore");
  69.     }
  70. }
  71.  
  72.  
  73. int main() {
  74.     // Создаем семафор
  75.     int semid = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT);
  76.     assert(semid != -1 && "Error: can't get IPC");
  77.  
  78.  
  79.     // Создаем очередь сообщений
  80.     int msgqid = msgget(IPC_PRIVATE, 0600 | IPC_CREAT);
  81.     assert(msgqid != -1 && "Error: can't get IPC");
  82.  
  83.  
  84.  
  85.     for (int i = 0; i < 4; i++) {
  86.         int pid = fork();
  87.         if (pid == CHILD) {
  88.             thread(semid, msgqid, i);
  89.             return 0;
  90.         }
  91.     }
  92.  
  93.     int status = 0;
  94.     while ((wait(&status)) > 0);
  95.  
  96.     msg msg_obj("");
  97.     for (int i = 0; i < 12; i++) {
  98.         int result = msgrcv(msgqid, &msg_obj, sizeof(msg), 1, IPC_NOWAIT);
  99.         assert(result != -1 && "Error: Can't read message to IPC");
  100.  
  101.         std::cout << msg_obj.mtext << std::endl;
  102.     }
  103.  
  104.     return 0;
  105. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment