Setting Timeout for C/C++ Function Call

Setting timeout for c/c++ function call

You can call this function in a new thread, and set a timeout to terminate the thread, it will end this function call.

A POSIX example would be:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>

pthread_t tid;

// Your very slow function, it will finish running after 5 seconds, and print Exit message.
// But if we terminate the thread in 3 seconds, Exit message will not print.
void * veryslow(void *arg)
{
fprintf(stdout, "Enter veryslow...\n");
sleep(5);
fprintf(stdout, "Exit veryslow...\n");

return nullptr;
}

void alarm_handler(int a)
{
fprintf(stdout, "Enter alarm_handler...\n");
pthread_cancel(tid); // terminate thread
}

int main()
{
pthread_create(&tid, nullptr, veryslow, nullptr);

signal(SIGALRM, alarm_handler);
alarm(3); // Run alarm_handler after 3 seconds, and terminate thread in it

pthread_join(tid, nullptr); // Wait for thread finish

return 0;
}

How to implement timeout for function in c++

You can create a separate thread to run the call itself, and wait on a condition variable back in your main thread which will be signalled by the thread doing the call to f once it returns. The trick is to wait on the condition variable with your 1s timeout, so that if the call takes longer than the timeout you will still wake up, know about it, and be able to throw the exception - all in the main thread. Here is the code (live demo here):

#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>

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<std::mutex> 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;
}

How to implement a timeout in read() function call?

select()
takes 5 parameters, first the highest file descriptor + 1, then a fd_set for read, one for write and one for exceptions. The last parameter is a struct timeval, used for timeout. It return -1 on error, 0 on timeout or the number of file descriptors in the sets that are set.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>

int main(void)
{
fd_set set;
struct timeval timeout;
int rv;
char buff[100];
int len = 100;
int filedesc = open( "dev/ttyS0", O_RDWR );

FD_ZERO(&set); /* clear the set */
FD_SET(filedesc, &set); /* add our file descriptor to the set */

timeout.tv_sec = 0;
timeout.tv_usec = 10000;

rv = select(filedesc + 1, &set, NULL, NULL, &timeout);
if(rv == -1)
perror("select"); /* an error accured */
else if(rv == 0)
printf("timeout"); /* a timeout occured */
else
read( filedesc, buff, len ); /* there was data to read */
close(filedesc);
}

Timeout Function

Probably this dummy program might help you:

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>

#define WAIT 3

int main ()
{
char name[20] = {0}; // in case of single character input
fd_set input_set;
struct timeval timeout;
int ready_for_reading = 0;
int read_bytes = 0;

/* Empty the FD Set */
FD_ZERO(&input_set );
/* Listen to the input descriptor */
FD_SET(STDIN_FILENO, &input_set);

/* Waiting for some seconds */
timeout.tv_sec = WAIT; // WAIT seconds
timeout.tv_usec = 0; // 0 milliseconds

/* Invitation for the user to write something */
printf("Enter Username: (in %d seconds)\n", WAIT);
printf("Time start now!!!\n");

/* Listening for input stream for any activity */
ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
/* Here, first parameter is number of FDs in the set,
* second is our FD set for reading,
* third is the FD set in which any write activity needs to updated,
* which is not required in this case.
* Fourth is timeout
*/

if (ready_for_reading == -1) {
/* Some error has occured in input */
printf("Unable to read your input\n");
return -1;
}

if (ready_for_reading) {
read_bytes = read(0, name, 19);
if(name[read_bytes-1]=='\n'){
--read_bytes;
name[read_bytes]='\0';
}
if(read_bytes==0){
printf("You just hit enter\n");
} else {
printf("Read, %d bytes from input : %s \n", read_bytes, name);
}
} else {
printf(" %d Seconds are over - no data input \n", WAIT);
}

return 0;
}

Update:

This is now tested code.

Also, I have taken hints from man for select. This manual already contains a code snippet which is being used to read from the terminal and timeout in 5 seconds in case of no activity.

Just a brief explanation in case the code is not well written enough:

  1. We add the input stream (fd = 1) to the FD set.
  2. We initiate select call to listen to this FD set created for
    any activity.
  3. In case any activity occurs within the timeout period, that is
    read through the read call.
  4. In case there was no activity, timeout occurs.

Hope this helps.

ACE C++ - How do I implement timeout for a function call?

Put the function in a separate thread. If the thread hasn't exited within the timeout, then detach it and let it run to finish in the background without getting any result from it.

Note that this won't work if the function has side-effects (like writing to a file).

C++: How to implement a timeout for an arbitrary function call?

You could spawn a boost::thread to call the API:

boost::thread api_caller(::api_function, arg1, arg2);
if (api_caller.timed_join(boost::posix_time::milliseconds(500)))
{
// API call returned within 500ms
}
else
{
// API call timed out
}

Boost doesn't allow you to kill the worker thread, though. In this example, it's just orphaned.

You'll have to be careful about what that API call does, because it may never release resources it's acquired.

Function timeouts in C and thread

There is no proper way to terminate a thread function other than letting it finish.


Every attempt to finish a thread from the outside could lead to resource (mostly but not only memory) leaks, state variables in nondeterministic state, and so. Please don't do it. Never. The normal way of terminating a thread function from the outside is to make it listen to some means of inter thread communication (which can be a sync object, a volatile variable or even a message loop), and exit the function core when it is necessary. Normally you would realize it by having a single test in the cycle condition of the thread if it is looping or testing before every long-running operation inside your thread.

Now if you store the timestamp of the function start and test at every cycle condition/long-running test if currenttimestamp > timestamp + timeout, you can exit from inside your thread and voilá; your problem is solved.



Related Topics



Leave a reply



Submit