Saltar al contenido

Cómo implementar el tiempo de espera para la función en c ++

Luego de de esta prolongada recopilación de información pudimos solucionar esta cuestión que presentan muchos los usuarios. Te compartimos la respuesta y nuestro deseo es resultarte de mucha apoyo.

Solución:

Puede crear un subproceso separado para ejecutar la llamada en sí y esperar una variable de condición en su subproceso principal que será señalado por el subproceso que realiza la llamada a f una vez que regresa. El truco es esperar en la variable de condición con su tiempo de espera de 1s, de modo que si la llamada toma más tiempo que el tiempo de espera, aún se despertará, lo sabrá y podrá lanzar la excepción, todo en el hilo principal. Aquí está el código (demostración en vivo aquí):

#include 
#include 
#include 
#include 
#include 

using namespace std::chrono_literals;

int f()

    std::this_thread::sleep_for(10s); //change value here to less than 1 second to see Success
    return 1;


int f_wrapper()

    std::mutex m;
    std::condition_variable cv;
    int retValue;

    std::thread t([&cv, &retValue]() 
    
        retValue = f();
        cv.notify_one();
    );

    t.detach();

    
        std::unique_lock l(m);
        if(cv.wait_for(l, 1s) == std::cv_status::timeout) 
            throw std::runtime_error("Timeout");
    

    return retValue;    


int main()

    bool timedout = false;
    try 
        f_wrapper();
    
    catch(std::runtime_error& e) 
        std::cout << e.what() << std::endl;
        timedout = true;
    

    if(!timedout)
        std::cout << "Success" << std::endl;

    return 0;

También puede usar std::packaged_task para ejecutar su función f() en otro hilo. Esta solución es más o menos similar a esta, solo que usa clases estándar para terminar.

std::packaged_task task(f);
auto future = task.get_future();
std::thread thr(std::move(task));
if (future.wait_for(1s) != std::future_status::timeout)

   thr.join();
   future.get(); // this will propagate exception from f() if any

else

   thr.detach(); // we leave the thread still running
   throw std::runtime_error("Timeout");

Probablemente incluso pueda intentar envolverlo en una plantilla de función, para permitir llamar a funciones arbitrarias con tiempo de espera. Algo del estilo de:

template 
std::result_of_t run_with_timeout(TF&& f, TDuration timeout, TArgs&&... args)

    using R = std::result_of_t;
    std::packaged_task task(f);
    auto future = task.get_future();
    std::thread thr(std::move(task), std::forward(args)...);
    if (future.wait_for(timeout) != std::future_status::timeout)
    
       thr.join();
       return future.get(); // this will propagate exception from f() if any
    
    else
    
       thr.detach(); // we leave the thread still running
       throw std::runtime_error("Timeout");
    

Y luego usa:

void f1()  ... 
call_with_timeout(f1, 5s);

void f2(int)  ... 
call_with_timeout(f2, 5s, 42);

int f3()  ... 
int result = call_with_timeout(f3, 5s);

Este es un ejemplo en línea: http://cpp.sh/7jthw

Puede crear un nuevo subproceso y esperar asincrónicamente a que pasen 1 y luego lanzar una excepción. Sin embargo, las excepciones solo se pueden capturar en el mismo subproceso en el que se lanzan, por lo que no se pueden capturar en el mismo subproceso en el que llamó f()como en su código de ejemplo, pero ese no es un requisito establecido, por lo que puede estar bien para usted.

Sólo si f se garantiza que regresará en menos de 1 segundo, ¿puede hacerlo de forma sincrónica?

  • almacenar la hora actual
  • llamar f()
  • esperar la hora actual - tiempo almacenado + 1s

Pero puede ser bastante difícil demostrar que f de hecho regresa a tiempo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *