AB
Jan. 28, 2019, 4:04 p.m.

Многопоточный калькулятор

C++, Qt

Здравствуйте.
Задача сделать так, чтобы программа работала в двух потоках. Нужно искусственно слипать поток, дабы эмулировать долгие вычисления.

В первом: 1. Формируется запрос на вычисление и происходит добавление его в очередь потока 2 (при нажатии на кнопку = ). 2. Вывод результатов (например в qDebug), полученных из потока 2

Во втором (доступ к потоку 2 должен быть потокобезопасным): 1. Как завершится пред. вычисление, преступать к следующему поступившему из потока 1. 2. Извлеченный элемент отправляется на обработку. 3. Ожидание окончания 4. Передача результата в основной поток

С библиотекой QThread не знаком, + читал о нескольких способах реализации, так и не понял как сделать грамотнее.

void MainWindow::equal_pressed()
{
    double displayNumber;
    double secondNum = ui->display->text().toDouble();
    QString DisplayText;

    if (ui->pushButton_add->isChecked())
    {
        qDebug() << "New request: " << firstNum << " + " << secondNum;
        std::thread thread_2([&displayNumber,secondNum,this](){displayNumber = compute(add,firstNum,secondNum); });
        thread_2.join();                                        // это конечно неправильно, выходит тоже самое что и в одном потоке. Где-то нужно создать std::queue мб и туда помещать запросы
        DisplayText = QString::number(displayNumber,'g',15);    // только как.
        ui->display->setText(DisplayText);
        ui->pushButton_add->setChecked(false);
        qDebug() << "Result: " << displayNumber;
    }
    else if (ui->pushButton_subtract->isChecked())
    {
        qDebug() << "New request: " << firstNum << " - " << secondNum;
        displayNumber = compute(substract,firstNum,secondNum);
        DisplayText = QString::number(displayNumber,'g',15);
        ui->display->setText(DisplayText);
        ui->pushButton_subtract->setChecked(false);
        qDebug() << "Result: " << displayNumber;
    }
    else if (ui->pushButton_mult->isChecked())
    {
        qDebug() << "New request: " << firstNum << " * " << secondNum;
        displayNumber = compute(mult,firstNum,secondNum);;
        DisplayText = QString::number(displayNumber,'g',15);
        ui->display->setText(DisplayText);
        ui->pushButton_mult->setChecked(false);
        qDebug() << "Result: " << displayNumber;
    }
    else if (ui->pushButton_divide->isChecked())
    {
        qDebug() << "New request: " << firstNum << " / " << secondNum;
        try
        {
            displayNumber = compute(divide,firstNum,secondNum);;
            if (secondNum == 0.0) {throw 1; }
            DisplayText = QString::number(displayNumber,'g',15);
            ui->display->setText(DisplayText);
            ui->pushButton_divide->setChecked(false);
            qDebug() << "Result: " << displayNumber;
        }
        catch (int e)
        {
            qDebug() << "Error: You cannot divide by zero!";
        }
        ui->pushButton_divide->setChecked(false);          //чтобы можно было продолжить пользоваться программой, после деления на 0
    }

    userTypingSecondDigit = false;
}

double MainWindow::compute(int Type, double OperandA, double OperandB)
{
    switch (Type) {
        case add:
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
            return OperandA + OperandB;
        }
        case substract:
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
            return OperandA - OperandB;
        }
        case mult:
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
            return OperandA * OperandB;
        }
        case divide:
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
            return OperandA / OperandB;
        }
    }
}

Просьба помочь разобраться с данной задачей. QT для меня в новинку

10% refund of hotel reservation amount on Booking
10% refund of hotel reservation amount on Booking
We offer a link with a 10% return on the amount of the order when booking a hotel through Booking
1

Добрый день!

Думаю, что вы можете воспользоваться QThread::moveToThread , как показано в статье.

Я бы на вашем месте создал класс внутренней логики калькулятора, который с помощью moveToThread будет передаваться в другой поток. Данный класс будет иметь свою рабочую петлю в которой будет ожидать данные для расчёта, данные можно будет помещать в QQueue с помощью сигнал/слотового соединения, аналогично извлекать данные с помощью сигнал слотового соединения. Соответственно в слотах нужно будет использовать QMutex, чтобы обезопасить данные.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
D
Aug. 16, 2019, 11:58 a.m.
Damir

C++ - Тест 003. Условия и циклы

  • Result:92points,
  • Rating points8
D
Aug. 16, 2019, 11:46 a.m.
Damir

C++ - Test 005. Structures and Classes

  • Result:75points,
  • Rating points2
u
Aug. 14, 2019, 1:55 p.m.
unrealproro

C++ - Test 005. Structures and Classes

  • Result:83points,
  • Rating points4
Last comments
Aug. 19, 2019, 6:41 a.m.
Andrej Jankovich

это проблема дистрибутива, попробуйте установить через пакетный менеджер snap Суть проблемы: libQt5Core которая лежит в дистрибутиве требует версию glibc >= 2.25 у вас видимо …
b
Aug. 18, 2019, 5:09 a.m.
bbb116

cqtdeployer /home/aleks/CQtDeployer/bin/cqtdeployer: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /home/aleks/CQtDeployer/lib/libQt5Core.so.5) linux mint …
D
Aug. 17, 2019, 8:04 a.m.
Damir

github ChekableTView Правой групповая смена значения при перетаскивании левой как обычно.
Aug. 16, 2019, 12:03 p.m.
Evgenij Legotskoj

Потому, что в минуте 60 секунд
Aug. 16, 2019, 11:16 a.m.
Dmitrij

а почему делитель 60000, а не 1000?
Now discuss on the forum
Aug. 19, 2019, 10:29 a.m.
Aleksej Vnukov

я в дороге, по тому примеру что в есть выше вам чтоб заработало нужно примерно следующее ListModel{ id: list_model } в ListView добавить model:list_model там где кноп…
Aug. 19, 2019, 8:47 a.m.
Pavel K.

bool YourClass::chekIfEmpty(const QString& table) { return getCount(table) == 0;}int YourClass::getCount(const QString& table, const QString& where) { QString command =…
Aug. 19, 2019, 8:29 a.m.
Pavel K.

посмотрите тут , практически тоже самое делал(пробегал по документу). А так в принципе : QFile file(Path);if(file.exist){ file.open(QIODevice::WriteOnly); // ReadWrite for…
Aug. 19, 2019, 2:39 a.m.
grig_p

Здравствуйте! Хотелось бы в своем приложении сделать цетрализованную обработку исключительных ситуаций для их логирования. Переопределил метод notify(): static const int EC_MAINLOOP…
Aug. 15, 2019, 2:19 a.m.
Mihailll

Плюсы и qml отличаются, с++ логичней
Looking for a Job?
14,000.00 руб. - 40,000.00 руб.
Разработчик Qt
Annino, Moscow Oblast, Russia
5,000.00 руб. - 15,000.00 руб.
Дизайнер
Moskovskiy, Moscow, Russia
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

For registered users on the site there is a minimum amount of advertising

EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB