kirya_shkolnik

multithread

Nov 20th, 2021 (edited)
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.53 KB | None | 0 0
  1. // mainwindow.cpp
  2.  
  3.  
  4. #include "mainwindow.h"
  5. #include "ui_mainwindow.h"
  6.  
  7.  
  8.  
  9. MainWindow::MainWindow(QWidget *parent)
  10.     : QMainWindow(parent)
  11.     , ui(new Ui::MainWindow)
  12. {
  13.     ui->setupUi(this);
  14.     mtcount = 1; // 1 поток
  15.     initMultiThread(); // инициализация одного потока
  16. }
  17. MainWindow::~MainWindow()
  18. {
  19.     delete ui;
  20. }
  21.  
  22.  
  23.  
  24.  
  25. void MainWindow::initMultiThread() // Инициализация mtcount количества потоков
  26. {
  27.     if(reinit)  log("Инициализация потоков: " ); // выводить логи только если идет реиницилазиция потоков
  28.     for (int i = 0; i < mtcount; i++)
  29.     {
  30.         multiThreads[i] = new my_thread(i + 1);
  31.         multiThreads[i]->start();
  32.         connect(multiThreads[i], &my_thread::statusUpdate, this, &MainWindow::multiThreadInfo);
  33.         QString stateText = "thread " + QString::number(i + 1) + ": " +  "Initialized"; // Вывод информации, что поток инициализирован
  34.         if(reinit) log(stateText); // выводить логи только если идет реиницилазиция потоков
  35.  
  36.     }
  37.     ui->label_threads->setText("Сейчас потоков: " + QString::number(mtcount)); // информация сколько потоков сейчас запущено
  38.     enableMTButtons(); // разблокировать кнопки
  39.     showMTButtons(); // показать кнопки если они спрятаны
  40.     if(reinit) log("Все потоки инициализированы"); // выводить логи только если идет реиницилазиция потоков
  41.     reinit = false; // нужна для кнопки реинициализации потоков. когда тру, тогда мы ждем удаления старых потоков и инициализируем новые (проверка в методе multiThreadInfo())
  42.  
  43.  
  44. }
  45.  
  46.  
  47.  
  48.  
  49.  
  50. // запуск работы потоков
  51. void MainWindow::on_pushButtonMultiThreadWork_clicked()
  52. {
  53.     log("Работа потоков: ");
  54.     setMultiThreadCommand(1, -1); // отправить команду 1 (работать) с временем -1 (когда мы отправляем -1, тогда время равняется рандомному)
  55.     unlockMultiThreadMutex(); // разлок мьютекса
  56.     disableMTButtons(); // отключение кнопок
  57. }
  58.  
  59.  
  60.  
  61. // Отправляет команду "умереть" потокам
  62. void MainWindow::on_pushButtonMultiThreadKill_clicked()
  63. {
  64.     log("Удаление потоков: ");
  65.     setMultiThreadCommand(2, -1);
  66.     unlockMultiThreadMutex(); // разлок мьютекса
  67.     hideMTButtons(); // спрятать кнопок
  68.     disableMTButtons(); // отключить кнопки
  69.  
  70.     //mtcount = 0;
  71.     ui->label_threads->setText("Сейчас потоков: 0"); // Все потоки мертвы. Потоков сейчас 0
  72. }
  73.  
  74.  
  75.  
  76. void MainWindow::on_pushButtonMultiThreadKill_2_clicked() // Нажатие на кнопку инициализировать потоки
  77. {
  78.     // Мы сначала удаляем все старые потоки, а потом инициализируем новые
  79.     reinit = true;
  80.     if(mtcount > 0){
  81.  
  82.         log("Удаление " + QString::number(mtcount) + " потоков для реинициализации: ");
  83.         setMultiThreadCommand(2, -1); // Отправить команду удалить с рандомным временем выполнения
  84.         unlockMultiThreadMutex(); // разлочить мьютекс
  85.         disableMTButtons(); // отключить кнопки
  86.  
  87.     }
  88.     else{
  89.  
  90.         mtcount =   ui->spinBox->value(); // новое кол-во потоков
  91.  
  92.         initMultiThread(); // инит потоков
  93.     }
  94. }
  95.  
  96.  
  97. // Установка команды на каждом потоке
  98. void MainWindow::setMultiThreadCommand(int command, int time)
  99. {
  100.     for (int i = 0; i < mtcount; i++) // перебор потоков
  101.         multiThreads[i]->setCommand(command, time); // отправка команды каждому потоку
  102. }
  103.  
  104. // Разблокивка мьютексов на всех потоках
  105. void MainWindow::unlockMultiThreadMutex()
  106. {
  107.     for (int i = 0; i < mtcount; i++) // перебор потоков
  108.         multiThreads[i]->unlock(); // разлок
  109. }
  110.  
  111.  
  112.  
  113.  
  114. void MainWindow::multiThreadInfo() // Вывод информации о потоке
  115. {
  116.     // Отображение информации об одном потоке (который вызвал данный сигнал)
  117.     auto threadSender = static_cast<my_thread *>(sender());
  118.     if (threadSender != nullptr)
  119.     {
  120.         QString stateText = "thread " + QString::number(threadSender->getNumber()) + ": ";
  121.        
  122.         switch (threadSender->getCommand()) {
  123.         case 3: // Поток выполнил работу
  124.             stateText += "Stopped ";
  125.             break;
  126.         case 4: // Поток умер
  127.             stateText += "Deleted ";
  128.             break;
  129.         }
  130.         stateText += QString::number(threadSender->getCounter()) + " ms"; // thread *number* : *command* *time* ms
  131.         log(stateText);
  132.     }
  133.  
  134.     // Если все потоки выполнили команды, то выводится информация об этом
  135.     if (isMultiThreadStopped())
  136.     {
  137.         log("Все потоки отработали и остановлены");
  138.         enableMTButtons(); // если все потокои остановились в выполнение задачи разлочить кнопки
  139.     }
  140.     else if (isMultiThreadKilled())
  141.     {
  142.         // Все потоки умерли
  143.         log("Все потоки удалены");
  144.         hideMTButtons(); // если все потокои умерли убрать кнопки
  145.  
  146.         mtcount = 0;
  147.         if(reinit){ // Если потоки убивались с целью реинициализиации
  148.             mtcount =   ui->spinBox->value(); // новое кол-во потоков
  149.  
  150.             initMultiThread(); // инит потоков
  151.  
  152.         }
  153.     }
  154. }
  155.  
  156. // Блокировка кнопок
  157. void MainWindow::disableMTButtons()
  158. {
  159.     ui->pushButtonMultiThreadWork->setEnabled(false);
  160.     ui->pushButtonMultiThreadKill->setEnabled(false);
  161.     ui->pushButtonMultiThreadKill_2->setEnabled(false);
  162.     ui->spinBox->setEnabled(false);
  163. }
  164. // Разблокировка кнопок
  165. void MainWindow::enableMTButtons()
  166. {
  167.     ui->pushButtonMultiThreadWork->setEnabled(true);
  168.     ui->pushButtonMultiThreadKill->setEnabled(true);
  169.     ui->pushButtonMultiThreadKill_2->setEnabled(true);
  170.     ui->spinBox->setEnabled(true);
  171.  
  172. }
  173. // Скрытие кнопок
  174. void MainWindow::hideMTButtons()
  175. {
  176.     ui->spinBox->setEnabled(true);
  177.     ui->pushButtonMultiThreadKill_2->setEnabled(true);
  178.     ui->pushButtonMultiThreadWork->hide();
  179.     ui->pushButtonMultiThreadKill->hide();
  180.  
  181. }
  182.  
  183. void MainWindow::showMTButtons()
  184. {
  185.     ui->spinBox->setEnabled(true);
  186.     ui->pushButtonMultiThreadKill_2->setEnabled(true);
  187.     ui->pushButtonMultiThreadWork->show();
  188.     ui->pushButtonMultiThreadKill->show();
  189.  
  190. }
  191.  
  192.  
  193. // Проверка потоков. Если все потоки остановились вернет true
  194. bool MainWindow::isMultiThreadStopped()
  195. {
  196.     for (int i = 0; i < mtcount; i++)
  197.     {
  198.         if (multiThreads[i]->getCommand() != 3)
  199.             return false;
  200.     }
  201.     return true;
  202. }
  203.  
  204. // Проверка потоков. Если все потоки умерли вернет true
  205. bool MainWindow::isMultiThreadKilled()
  206. {
  207.     if(mtcount == 0) return true;
  208.     for (int i = 0; i < mtcount; i++)
  209.     {
  210.  
  211.         if (multiThreads[i]->getCommand() != 4)
  212.             return false;
  213.     }
  214.     return true;
  215. }
  216.  
  217.  
  218.  
  219. // Обработчик нажатия на кнопку очистить текст
  220. void MainWindow::on_pushButtonClear_clicked()
  221. {
  222.     ui->textEdit->clear();
  223. }
  224.  
  225.  
  226. // Логирование в textEdit
  227. void MainWindow::log(QString content)
  228. {
  229.     ui->textEdit->append(content);
  230. }
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237. //
  238. //
  239. //
  240. //
  241. //
  242. //
  243. //
  244. //
  245. //
  246. //
  247. //
  248. //
  249. //
  250. //
  251. //
  252. //
  253. //
  254. //
  255. //
  256. //
  257.  
  258. // mainwindow.h
  259.  
  260. #ifndef MAINWINDOW_H
  261. #define MAINWINDOW_H
  262.  
  263.  
  264. #include <QMainWindow>
  265. #include "my_thread.h"
  266.  
  267.  
  268. QT_BEGIN_NAMESPACE
  269. namespace Ui { class MainWindow; }
  270. QT_END_NAMESPACE
  271.  
  272. class MainWindow : public QMainWindow
  273. {
  274.     Q_OBJECT
  275.  
  276. public:
  277.     explicit MainWindow(QWidget *parent = nullptr);
  278.     ~MainWindow();
  279.  
  280.    int mtcount;
  281.    int time;
  282.    bool reinit = false;
  283.  
  284.    my_thread *multiThreads[100];
  285.  
  286. private slots:
  287.  
  288.  
  289.  
  290.  
  291.     void on_pushButtonMultiThreadWork_clicked();
  292.     void on_pushButtonMultiThreadKill_clicked();
  293.  
  294.  
  295.     void multiThreadInfo();
  296.  
  297.     void on_pushButtonClear_clicked();
  298.  
  299.  
  300.     void on_pushButtonMultiThreadKill_2_clicked();
  301.  
  302. private:
  303.     Ui::MainWindow *ui;
  304.  
  305.     void initLoopThread();
  306.     void initMultiThread();
  307.  
  308.     void setMultiThreadCommand(int command, int time);
  309.     void unlockMultiThreadMutex();
  310.     bool isMultiThreadStopped();
  311.     bool isMultiThreadKilled();
  312.  
  313.     void log(QString text);
  314.  
  315.     void logLoopState(my_thread *thread);
  316.  
  317.     void disableLLButtons();
  318.     void enableLLButtons();
  319.     void hideLLButtons();
  320.     void showLLButtons();
  321.  
  322.     void disableMTButtons();
  323.     void enableMTButtons();
  324.     void hideMTButtons();
  325.     void showMTButtons();
  326. };
  327. #endif // MAINWINDOW_H
  328.  
Add Comment
Please, Sign In to add comment