es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo lograr que un subproceso en multiprocesamiento termine primero y el hilo principal continúe ejecutándose.

Intento implementar una función: el hilo principal crea múltiples sub-hilos y bloquea al hilo principal, y despierta al hilo principal para continuar la ejecución cuando cualquiera de los sub-hilos termina.

El siguiente código es mi intento de usar std::future en C++11:

std::pair<size_t, size_t=""> fun(size_t i, size_t j)
{
    std::this_thread::sleep_for(std::chrono::seconds(i * j));
    return { i, j };
}

int main()
{
    std::shared_future<><size_t, size_t="">> ret;
    std::pair<size_t, size_t=""> temp;

    ret = std::async(std::launch::async, fun, 10, 9);
    ret = std::async(std::launch::async, fun, 5, 4);
    ret = std::async(std::launch::async, fun, 2, 1);
    temp = ret.get();
    std::cout << temp.first << "\t" << temp.second << "\n";

    return 0;
}

Para el resultado, espero que el programa produzca directamente “2 1” después de (2 * 1) segundos y termine el hilo principal, pero en mi intento, el programa necesita esperar a que el primer sub-hilo duerma por (10 * 9) segundos antes de producir “2 1” y finalizar el hilo principal.</size_t,></size_t,></size_t,>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para lograr el resultado deseado de bloquear el hilo principal y despertarlo cuando uno de los sub-hilos termine, podemos hacer uso de std::promise y std::future. Aquí hay una posible implementación:

    // función que toma un objeto std::promise y devuelve void
    void sub_thread(std::promise<><size_t, size_t="">>& promise, size_t i, size_t j)
    {
        std::this_thread::sleep_for(std::chrono::seconds(i * j));
        promise.set_value({i, j}); // establecer el valor para el futuro asociado
    }
    
    int main()
    {
        std::promise<><size_t, size_t="">> promise1, promise2, promise3;
        std::future<><size_t, size_t="">> future1 = promise1.get_future();
        std::future<><size_t, size_t="">> future2 = promise2.get_future();
        std::future<><size_t, size_t="">> future3 = promise3.get_future();
    
        // crear los sub-hilos y pasarles las promesas
        std::thread t1(sub_thread, std::ref(promise1), 10, 9);
        std::thread t2(sub_thread, std::ref(promise2), 5, 4);
        std::thread t3(sub_thread, std::ref(promise3), 2, 1);
    
        // bloquear el hilo principal hasta que alguno de los futuros esté listo
        std::vector<><><size_t, size_t="">>> futures;
        futures.push_back(std::move(future1));
        futures.push_back(std::move(future2));
        futures.push_back(std::move(future3));
        auto result = std::experimental::when_any(futures.begin(), futures.end()).get();
    
        // imprimir el resultado y finalizar el hilo principal
        std::cout << result.first->get().first << "\t" << result.first->get().second << "\n";
        t1.join();
        t2.join();
        t3.join();
    
        return 0;
    }
    

    En esta implementación, creamos tres promesas y futuros asociados, uno para cada sub-hilo. Luego creamos los sub-hilos y les pasamos las promesas como argumentos de referencia. Los sub-hilos llaman a la función sub_thread, que duerme durante la cantidad de tiempo especificada y luego establece el valor para la promesa asociada usando el método set_value.

    En el hilo principal, creamos un vector de futuros y empujamos los tres futuros en él. Luego usamos la función when_any del espacio de nombres experimental (ya que aún no es parte del estándar en el momento de escribir esto) para bloquear el hilo principal hasta que alguno de los futuros esté listo. Esta función devuelve un par que consiste en un iterador al futuro listo y un índice entero que indica su posición en el vector de futuros. Usamos el método get para recuperar el par de valores almacenados en el futuro listo e imprimirlos. Finalmente, unimos los sub-hilos y regresamos.</size_t,></size_t,></size_t,></size_t,></size_t,></size_t,>

Comments are closed.