¿Hay alguna manera de cancelar / separar un futuro en C ++ 11?

Tengo el siguiente código:

#include  #include  #include  #include  using namespace std; int sleep_10s() { this_thread::sleep_for(chrono::seconds(10)); cout << "Sleeping Done\n"; return 3; } int main() { auto result=async(launch::async, sleep_10s); auto status=result.wait_for(chrono::seconds(1)); if (status==future_status::ready) cout << "Success" << result.get() << "\n"; else cout << "Timeout\n"; } 

Se supone que esto debe esperar 1 segundo, imprimir “Tiempo de espera” y salir. En lugar de salir, espera 9 segundos adicionales, imprime “Sleeping Done” y luego segfaults. ¿Hay alguna forma de cancelar o desconectar el futuro, de modo que mi código saldrá al final de main en lugar de esperar a que el futuro termine de ejecutarse?

El estándar C ++ 11 no proporciona una forma directa de cancelar una tarea iniciada con std::async . Deberá implementar su propio mecanismo de cancelación, como pasar una variable de indicador atómico a la tarea asíncrona que se verifica periódicamente.

Sin embargo, su código no debería fallar. Al llegar al final de main , se destruye el objeto std::future contenido en el result , que esperará a que la tarea finalice, y luego descartará el resultado, limpiando todos los recursos utilizados.

Aquí un ejemplo simple usando un bool atómico para cancelar uno o múltiples futuros al mismo tiempo. El bool atómico puede estar envuelto dentro de una clase de cancelación (dependiendo del gusto).

 #include  #include  #include  using namespace std; int long_running_task(int target, const std::atomic_bool& cancelled) { // simulate a long running task for target*100ms, // the task should check for cancelled often enough! while(target-- && !cancelled) this_thread::sleep_for(chrono::milliseconds(100)); // return results to the future or raise an error // in case of cancellation return cancelled ? 1 : 0; } int main() { std::atomic_bool cancellation_token; auto task_10_seconds= async(launch::async, long_running_task, 100, std::ref(cancellation_token)); auto task_500_milliseconds = async(launch::async, long_running_task, 5, std::ref(cancellation_token)); // do something else (should allow short task // to finish while the long task will be cancelled) this_thread::sleep_for(chrono::seconds(1)); // cancel cancellation_token = true; // wait for cancellation/results cout << task_10_seconds.get() << " " << task_500_milliseconds.get() << endl; }