如何在C中设置函数的超时?

我要求我必须给xx ms执行一个函数。 在xx ms之后我必须中止该function。 请帮我解决如何在C中实现它。

我认为最好的方法是使用pthreads。 启动可能需要在其自己的线程中取消的计算,并在主线程中使用pthread_cond_timedwait:

#include  #include  #include  /* for ETIMEDOUT */ #include  #include  pthread_mutex_t calculating = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t done = PTHREAD_COND_INITIALIZER; void *expensive_call(void *data) { int oldtype; /* allow the thread to be killed at any time */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); /* ... calculations and expensive io here, for example: * infinitely loop */ for (;;) {} /* wake up the caller if we've completed in time */ pthread_cond_signal(&done); return NULL; } /* note: this is not thread safe as it uses a global condition/mutex */ int do_or_timeout(struct timespec *max_wait) { struct timespec abs_time; pthread_t tid; int err; pthread_mutex_lock(&calculating); /* pthread cond_timedwait expects an absolute time to wait until */ clock_gettime(CLOCK_REALTIME, &abs_time); abs_time.tv_sec += max_wait->tv_sec; abs_time.tv_nsec += max_wait->tv_nsec; pthread_create(&tid, NULL, expensive_call, NULL); /* pthread_cond_timedwait can return spuriously: this should * be in a loop for production code */ err = pthread_cond_timedwait(&done, &calculating, &abs_time); if (err == ETIMEDOUT) fprintf(stderr, "%s: calculation timed out\n", __func__); if (!err) pthread_mutex_unlock(&calculating); return err; } int main() { struct timespec max_wait; memset(&max_wait, 0, sizeof(max_wait)); /* wait at most 2 seconds */ max_wait.tv_sec = 2; do_or_timeout(&max_wait); return 0; } 

你可以在linux上编译并运行它:

 $ gcc test.c -pthread -lrt && ./a.out do_or_timeout: calculation timed out 

如果您不使用pthread,您还可以使用Apache Portable Runtime执行类似的超时function: http : //apr.apache.org/docs/apr/1.4/group__apr__thread__proc.html

 #include  #include  #include  #include "apr.h" #include "apr_thread_proc.h" #include "apr_time.h" void *APR_THREAD_FUNC expensive_call(apr_thread_t *thread, void *data) { (void)thread; bool *done = data; /* ... calculations and expensive io here, for example: * infinitely loop */ for (;;) {} // signal caller that we are done *done = true; return NULL; } bool do_or_timeout(apr_pool_t *pool, apr_thread_start_t func, int max_wait_sec) { apr_thread_t *thread; bool thread_done = false; apr_thread_create(&thread, NULL, func, &thread_done, pool); apr_time_t now = apr_time_now(); for (;;) { if (thread_done) { apr_thread_join(NULL, thread); return true; } if (apr_time_now() >= now + apr_time_make(max_wait_sec, 0)) { return false; } // avoid hogging the CPU in this thread apr_sleep(10000); } } int main(void) { // initialize APR apr_initialize(); apr_pool_t *ap; if (apr_pool_create(&ap, NULL) != APR_SUCCESS) { exit(127); } // try to do the expensive call; wait up to 3 seconds bool completed = do_or_timeout(ap, expensive_call, 3); if (completed) { printf("expensive_call completed\n"); } else { printf("expensive_call timed out\n"); } apr_terminate(); return 0; } 

使用这样的命令编译

gcc -o example example.c -lapr-1

 ->include time.h ->take two variable for start time & current time of type time_t like time_t start_time,current_time -> take start time time(&start_time); now in while loop continuisly check for time(&current_time) difftime(current_time,start_time) if difftime's return value is 15ms break while loop & close your program 

我不知道那种架构,所以我只能给你一个一般性的提示。 我会尝试类似于旧的Symbian TRAP机制。

  1. 在主程序中:

    • 启动计时器。
    • 收起堆栈指针
    • 收起一个程序柜台。
    • 打电话给你的function
  2. 在定时器exception(中断)处理例程中。 这有点棘手,因为当exception处理开始时,您需要知道给定的体系结构堆栈指针和程序计数器的位置(处理器的数据表)。程序计数器很可能被推送到主程序堆栈。 所以你的步骤是:

    • 用复制的值替换堆栈指针值(对于主例程)。
    • 用您复制的值+偏移量替换程序计数器值(因为您希望在函数调用后返回执行 – 最好检查汇编代码以确定它有多大)。
    • 从exception(中断)处理例程返回。

@Bobby Powers的答案是工作,但需要稍微改动如下

 if (!err) pthread_mutex_unlock(&calculating); -> change to pthread_mutex_unlock(&calculating); as @TD Smith says and need add pthread_cancel(tid) // if isn't add, the expensive_call may never exit if your function couldn't exit by itself, such as for (;;) {} or something block operation.