Завершение функции в C ++

0

У меня есть функция C++, называемая write() которая должна записывать большое количество байтов на жесткий диск пользователя. Этот шум обычно занимает более 30 секунд, поэтому я хочу дать пользователю возможность Abort operation из графического интерфейса (созданного с помощью Qt).

Поэтому у меня есть кнопка generate_button. Когда эта кнопка clicked(), я хочу иметь что-то, чтобы положить конец функции, где бы ни был ее прогресс.

Я думал о потоках, но я не уверен. Можете ли вы мне посоветовать?

Теги:
function
qt

3 ответа

2
Лучший ответ

Я бы, вероятно, использовал нить. Это должно быть довольно просто проверить переменную, чтобы увидеть, была ли операция отменена.

Используйте мьютекс, чтобы заблокировать доступ к вашей переменной отмены. Это обеспечит правильное чтение и запись для нескольких потоков. Другой вариант - если вы используете С++ 11, используйте атомную переменную.

Разбейте свою большую запись на блоки меньшего размера. От 8 до 64 килобайт должно работать. После записи каждого блока проверьте свою отмененную переменную, и если она установлена, выйдите из потока.

  • 0
    да, я использую C ++ 11. Я собираюсь принять ваш ответ, но не могли бы вы написать код для демонстрации атомарной переменной, пожалуйста?
  • 0
    @Victor: Я украл ссылочную ссылку на атомные атомы у Зака и вставил ее в свой ответ.
2

Поместите код, который на самом деле записывается в рабочий поток. Имейте общую переменную (ту, которая является либо атомной, либо защищена мьютексом). Попросите рабочий поток проверить его значение на каждой итерации. Если пользователь нажимает кнопку "Отмена", задайте значение для переменной.

Вы должны использовать потоки, если это длительная операция.

Поскольку вы используете С++ 11, std::atomic<bool>, вероятно, послужит вам хорошо.

  • 0
    Что ж, в Windows это можно сделать без потоков, используя цикл с write и PeekMessage. Qt, вероятно, имеет нечто подобное.
  • 0
    @ZanLynx Даже если вы используете функции OverlappedIO, под вами все равно создается поток. Единственный способ действительно сделать это полностью без отдельного потока - это сделать что-то в ответ на конкретное сообщение (например, WM_IDLE), которое становится очень грязным.
Показать ещё 1 комментарий
1

Резьбовое гарантирует, что у вас будет гибкий графический интерфейс. Но есть кривая обучения использованию потока таким образом.

Бесполезный способ сделать это - иметь в своей рутине, которая записывает на жесткий диск в потоке графического интерфейса пользователя, но дает время, чтобы поток GUI оставался отзывчивым.

QObject::connect(my_cancel_button, SIGNAL(clicked()), file_writer, SLOT(setCanceled()));

// open file for writing
QFile file("filename.txt");
file.open(//... );//

while(still_have_data_to_write && !canceled)
{
    write( <1 MB of data> ); // or some other denomination of data

    qApp->processEvents();// allows the gui to respond to events such as clicks on buttons

    // update a progress bar... using a counter as a ratio of the total file size
    emit updateProgressBar(count++);
}

if( canceled )
{
     file.close();
     // delete the partial file using QDir
}

Надеюсь, это поможет.

  • 0
    Я попробую метод как можно скорее, но я думаю, что оставлю ответ, который уже принял, потому что Моя библиотека предназначена для работы на чистом C ++, без какой-либо другой библиотеки (как вы упоминали здесь о Qt)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню