Как я могу отменить функцию std :: async?

Возможный дубликат:
Есть ли способ отменить / отключить будущее в C ++ 11?

Есть функция-член, которая работает асинхронно, используя std::future а также std::async, В некоторых случаях мне нужно отменить это. (Функция загружается рядом с объектами последовательно, и иногда объекты выходят за пределы диапазона во время загрузки.) Я уже читал ответы на этот вопрос решая ту же проблему, но я не могу заставить ее работать.

Это упрощенный код с той же структурой, что и у моей настоящей программы. призвание Start() а также Kill() в то время как асинхронный работает, вызывает сбой из-за нарушения прав доступа для input,

На мой взгляд код должен работать следующим образом. когда Kill() вызывается, флаг запуска отключен. Следующая команда get() следует дождаться окончания потока, что он и делает в ближайшее время, так как проверяет флаг выполнения. После отмены обсуждения input указатель удален

#include <vector>
#include <future>
using namespace std;

class Class
{
future<void> task;
bool running;
int *input;
vector<int> output;

void Function()
{
for(int i = 0; i < *input; ++i)
{
if(!running) return;
output.push_back(i);
}
}

void Start()
{
input = new int(42534);
running = true;
task = async(launch::async, &Class::Function, this);
}

void Kill()
{
running = false;
task.get();
delete input;
}
};

Кажется, что поток не замечает переключение флага выполнения на false. В чем моя ошибка?

6

Решение

Поскольку на самом деле никто еще не ответил на вопрос, я сделаю это.

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

Один из возможных способов — это то, что компилятор анализирует код Function, определяет, что в переменную в этом потоке никогда не производится запись в переменную, и, поскольку это не атомарный объект, запись другими потоками не обязательно должна быть видимой, поэтому вполне законно переставить код следующим образом:

void Function()
{
if(!running) return;
for(int i = 0; i < *input; ++i)
{
output.push_back(i);
}
}

Очевидно, в этом коде, если running Изменения после запуска функции не приведут к остановке цикла.

Стандарт C ++ позволяет синхронизировать два потока двумя способами: использовать мьютекс и только читать или записывать running переменная, когда мьютекс заблокирован, или сделать переменную атомарной переменной. В вашем случае меняется running от bool в atomic<bool> будет гарантировать, что записи в переменную синхронизируются с чтениями из нее, и асинхронный поток будет прерван.

8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]