Advertisement
Guest User

Untitled

a guest
Mar 31st, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.68 KB | None | 0 0
  1. #define MAX_AMOUNT_OP_PROCESSES 500
  2.  
  3. #include <unistd.h>
  4. #include <signal.h>
  5. #include <sys/wait.h>
  6. #include <termios.h>
  7. #include <ncurses.h>
  8.  
  9. #include <vector>
  10. #include <iostream>
  11.  
  12. using namespace std;
  13.  
  14. vector<pid_t> procInfo;                         // Вектор идентификаторов процессов
  15. struct sigaction printSignal;                                           // Указатель на структуру Sigaction, обработчика сигналов
  16. bool Print = true;                                                      // Переменная для проверки разрешения на печать                                                      
  17. char parentPID[256];                                                    // Переменная для заполнения идентификатором родителя
  18. int counter= 0;                                                         // Счетчик процессов
  19.  
  20. int myGetch()                                                           // Реализация функции getch() для *nix систем
  21. {          
  22.    struct termios oldattr, newattr;
  23.    int ch;
  24.    tcgetattr(STDIN_FILENO, &oldattr);
  25.    newattr = oldattr;
  26.    newattr.c_lflag &= ~(ICANON | ECHO);
  27.    tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
  28.    ch = getchar();
  29.    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
  30.    return ch;
  31. }
  32.  
  33. void setPrint(int sig)                                                   // Проверка на возможность печати
  34. {
  35.    if (procInfo.size())                                                  // Проверка есть ли содержимое в векторе
  36.    {
  37.       if (++counter >= procInfo.size())                                  // Если counter выходит за рамки количества процессов
  38.          counter = 0;                                                    // то обнуляем его
  39.       napms(150);                                                        // приостановить процесс вызова
  40.       kill(procInfo[counter], SIGUSR1);                                  // вызов процессов
  41.  
  42.    }
  43.     else {
  44.       Print = true;
  45.    }
  46. }
  47.  
  48. void initSignalHandlers()                                                 // Установка значений структуры sigaction
  49. {
  50.    printSignal.sa_handler = setPrint;                                     // Обработчик сигнала старого стиля устанавливается в разрешенное для печати состояние
  51.    printSignal.sa_flags =  SA_RESTART;                                    // Флаг восстановление прерванных системных вызовов после выхода из обработчика
  52.    sigaction(SIGUSR1,                                                     // Номер сигнала
  53.              &printSignal,                                                // Указатель на структуру Sigaction
  54.              NULL);                                                       // если null то будет вызывать старый обработчик сигналов, без установки нового
  55. }
  56.  
  57. void addOneProcess()  
  58. {
  59.    procInfo.push_back(fork());                                            // Создаем дубликат родительского процесса и добавляем новый pid в вектор
  60.  
  61.    if (procInfo.back() == 0) {                                            // Проверка на пустоту вектора
  62.       char instanceID[10];                                                // Сюда помещается текущее количество процессов
  63.       sprintf(instanceID, "%d", procInfo.size());                         // Заполнение буфера текущим значением кол-ва процессов
  64.       if (execlp("./child", instanceID, parentPID, NULL) == -1) {         // Попытка вызвать новый процесс с переданными значениями командной строки в виде pid parent и кол-ва процессов
  65.          procInfo.pop_back();                                             // Если не удалось то удалить значение из вектора
  66.          cout << "Error in execlp." << endl;
  67.       }
  68.    }
  69. }
  70.  
  71. void removeOneProcess()
  72. {
  73.    kill(procInfo.back(), SIGUSR2);                                        // Передача сигнала на закрытие процесса
  74.    waitpid(procInfo.back(), NULL, 0);                                     // Приостанавливает выполнение текущего процесса до тех пор, пока дочерний процесс, указанный в параметре pid, не завершит выполнение
  75.    procInfo.pop_back();                                                   // Удаление последнего значения из вектора
  76. }
  77.  
  78. void showOptionList()
  79. {
  80.     system("clear");
  81.     cout << "Press..\n";
  82.     cout << "   '+' to create new child;" << endl;
  83.     cout << "   '-' to delete last child;" << endl;
  84.     cout << "   'q' to quit;\n" << endl;
  85. }
  86.  
  87. int main()
  88. {
  89.    showOptionList();
  90.  
  91.    initSignalHandlers();
  92.    sprintf(parentPID, "%d", getpid());                                    // Получение pid родительского процесса
  93.  
  94.     while (true) {
  95.       switch(myGetch()) {
  96.          case '+':
  97.             if(procInfo.size() < MAX_AMOUNT_OP_PROCESSES)
  98.             {
  99.                addOneProcess();                                          // Добавление нового процесса
  100.                if (Print == true) {
  101.                   napms(150);  
  102.                   kill(procInfo.back(), SIGUSR1);                        // Вызов сигнала SIGUSR1 для нового процесса
  103.                   Print = false;                                        
  104.                }
  105.             }
  106.             break;
  107.          
  108.           case '-':
  109.             if (!procInfo.empty())
  110.             {
  111.                if (counter == procInfo.size() - 1) {
  112.                   removeOneProcess();
  113.                   raise(SIGUSR1);                                       // Отправляет сигнал вызывающему процессу или потоку
  114.                }
  115.                 else
  116.         {
  117.             removeOneProcess();
  118.         }
  119.             }
  120.             break;
  121.              
  122.          case 'q':
  123.             while (!procInfo.empty()) {                                  // Очистка системы от процессов
  124.                removeOneProcess();
  125.             }
  126.             return 0;
  127.       }
  128.    }
  129. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement