resueltos - C++: valor de retorno simple de std:: thread?
tir ejemplo (5)
Con los subprocesos win32, tengo el sencillo GetExitCodeThread()
que me da el valor que devolvió la función del subproceso. Estoy buscando algo similar para std::thread
(o boost threads)
Según tengo entendido, esto se puede hacer con futuros, pero ¿cómo exactamente?
Creo que una variable de referencia se lee mucho más intuitivamente.
int x = 0;
std::thread theThread(threadFunction, std::ref(x));
theThread.join();
std::cout << x << std::endl;
Todo depende de tu definición de "simple".
El uso de futuros ciertamente hará el truco de magia en unas pocas líneas de C ++, pero me parece discutible secuestrar un mecanismo que fue diseñado para el procesamiento paralelo para un uso tan trivial.
los futuros en su mayoría tienen sentido en el CPUS multinúcleo, donde permiten que un proceso inicie tareas no sincronizadas que le permitirán liberar el poder de cómputo de los otros núcleos (dejando de lado el hecho de que encontrar un conjunto de datos sin núcleo lo suficientemente grande como para que valga la pena el esfuerzo no es tan trivial importa tampoco).
El uso de todo el mecanismo como solución alternativa para recuperar un mero valor de retorno int es lo que llamo diseño de software basado en la sintaxis. Se asemeja bastante a un escaparate de la versatilidad de C ++ 11, pero oculta un consumo considerable de recursos bajo una capa de azúcar sintáctica.
Si no es por usar otros núcleos como fuente de energía sin procesar, ¿cuál es el punto de crear un hilo si no quiere comunicarse con él hasta que esté listo?
Porque si lo hace, recuperar cualquier estado de él, ya sea en el momento de la rescisión o en cualquier otro momento, será un asunto trivial y ni siquiera se le ocurrirá usar futuros en primer lugar.
Excepto por la conveniencia (discutible) o el atractivo estético, ¿qué tipo de trucos de este tipo logran funcionalmente que puedan considerarse lo suficientemente útiles para compensar los costos ocultos?
Al leer tales respuestas sin un fondo de tareas múltiples adecuado, los nuevos niños en el bloque pueden verse tentados al usar este tipo de mecanismos ineficientes de forma regular.
Eso solo contaminaría el software futuro con más casos de síndrome de Schlemiel el Pintor .
Usando subprocesos de C ++ 11, uno no puede obtener el valor de retorno como salida de subproceso que solía ser el caso con pthread_exit(...)
Debe usar C ++ 11 Future<>
para obtener el valor de retorno. El futuro se crea utilizando un argumento con plantilla donde la plantilla toma el valor de retorno (integrado en los tipos definidos por el usuario).
Puede obtener el valor en otro hilo usando la función future<..>::get(..)
.
Un beneficio de usar el future<..>
es que puede verificar la validez del valor de retorno, es decir, si ya se tomó, evita llamar a get()
accidentalmente al verificar la validez usando el future<..>::isValid(...)
función.
Así es como escribirás el código.
#include <iostream>
#include <future>
using namespace std;
auto retFn() {
return 100;
}
int main() {
future<int> fp = async(launch::async, retFn);
if(fp.valid())
cout<<"Return value from async thread is => "<<fp.get()<<endl;
return 0;
}
También se debe tener en cuenta que podemos ejecutar el futuro en el mismo subproceso mediante el launch::deferred
opción launch::deferred
como
future<int> fp = async(launch::deferred, retFn);
Vea este video tutorial sobre los futuros de C ++ 11.
Explícitamente con hilos y futuros:
#include <thread>
#include <future>
void func(std::promise<int> && p) {
p.set_value(1);
}
std::promise<int> p;
auto f = p.get_future();
std::thread t(&func, std::move(p));
t.join();
int i = f.get();
O con std::async
(envoltorio de nivel superior para subprocesos y futuros):
#include <thread>
#include <future>
int func() { return 1; }
std::future<int> ret = std::async(&func);
int i = ret.get();
No puedo comentar si funciona en todas las plataformas (parece funcionar en Linux, pero no funciona para mí en Mac OSX con GCC 4.6.1).
Yo diría que:
#include <thread>
#include <future>
int simplefunc(std::string a)
{
return a.size();
}
int main()
{
auto future = std::async(simplefunc, "hello world");
int simple = future.get();
return simple;
}
Tenga en cuenta que async incluso propaga cualquier excepción lanzada desde la función de hilo