Hello everyone and again the question about multithreading, I post the source code of the test example. And immediately to the question, there is a calculation code that works in the stream, we can forcibly close it using the stop flag by pressing a button and at the end of the function send the emit finished () signal everything works. But when we in a stream function call the function that is defined in the dll that we perceive as a black box, that is, the stream accesses it, its arguments contain data and inside it are calculated, in the dll itself, how does it forcibly interrupt and delete a stream? there are no flags and signals about its interruption inside it, it works until it calculates. Counts inside a couple of minutes and we wait for the return value, and only on exiting it our stream is interrupted, and then it is deleted by our flag and the finished signal finished (). And again, so how to interrupt the forced flow? even if inside the dll function is still being calculated, without waiting for the return value? I spread a test working example for a reference point.
worker.cpp
#include "worker.h" #include <QDebug> Worker::Worker(QObject *parent) : QObject(parent) { Stop = false; temp = 0; } Worker::~Worker() { qDebug() << "destruction Thread"; } void Worker::process() { Stop = false; if(!Stop == true) { for (; temp <= 100000; temp++) { if(!Stop == true) { emit(sendNumber(temp)); qDebug() << temp; // ЗДЕСЬ БУДЕТ ВЫЗЫВАТСЯ ФУНКЦИЯ ИЗ DLL // в её аргументы будут поступать данные и внутри обрабатываться очень долго // до 2-3 минут обработки и возвращать значения // но нам нужно сразу ее прервать, даже если она еще внутри расчитывает } else { return; } } } emit finished(); // вызывается при завершении расчёта } void Worker::reciveBoolStop(bool Numb) { Stop = Numb; qDebug() << "reciveBoolStop = " << Stop; emit finished(); // вызывается при отмене расчёта }
worker.h
#ifndef WORKER_H #define WORKER_H #include <QObject> class Worker : public QObject { Q_OBJECT public: explicit Worker(QObject *parent = 0); ~Worker(); bool Stop; int temp; signals: void finished(); //void error(QString err); void sendNumber(int); public slots: void process(); void reciveBoolStop(bool Numb); }; #endif // WORKER_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include <QtCore> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(this->ui->pushButton_start, SIGNAL(clicked()), this, SLOT(startGUI())); connect(this->ui->pushButton_stop, SIGNAL(clicked()), this, SLOT(stopGUI())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::startGUI() { // Создание потока QThread* thread = new QThread; Worker* worker = new Worker(); // Передаем права владения "рабочим" классом, классу QThread. worker->moveToThread(thread); // Соединяем сигнал started потока, со слотом process "рабочего" класса, т.е. начинается выполнение нужной работы. connect(thread, SIGNAL(started()), worker, SLOT(process())); // Отображаем в главном потоке Gui, значения из вторичного потока connect(worker, SIGNAL(sendNumber(int)), this, SLOT(LineEditUi(int))); // Оповещаем поток, что нужно остановиться connect(this, SIGNAL(sendNumberBoolStop(bool)), worker, SLOT(reciveBoolStop(bool)), Qt::DirectConnection); // ВЫЗЫВАЕТ УТЕЧКУ ПАМЯТИ //connect(worker, SIGNAL(finished()), thread, SLOT(quit())); // По завершению выходим из потока, и удаляем рабочий класс connect(worker, SIGNAL(destroyed(QObject*)), thread, SLOT(quit())); // ТАК ПРАВИЛЬНО connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); // Удаляем поток, после выполнения операции connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); } void MainWindow::LineEditUi(int number) { ui->lineEdit->setText(QString::number(number)); } void MainWindow::stopGUI() { Stop = true; qDebug() << Stop; sendNumberBoolStop(Stop); qDebug() << "sendMumberBoolStop = " << Stop; }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "worker.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); bool Stop; public slots: void startGUI(); void stopGUI(); void LineEditUi(int number); signals: void sendNumberBoolStop(bool); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }