设定Linux C/C++ 程序的执行时限

设定Linux C/C++ 程序的执行时限
给Linux C/C程序设定执行时限时间管理是每个现代人的必修课。给一个任务固定的执行时间是控制整体进度的一种常用方法。如何让一个运行时间可能比较长的Linux C/C程序能够有一个执行时限呢这就是本文要解答的一个问题。方法一最直接的做法就是起一个timer设定该timer到期发送SIGTERM信号。如果定时器超时后需要做善后工作那么就给SIGTERM信号写一个信号处理函数若不需要善后工作则不用写。// g timer.cpp -lrt#includectime#includecstdlib#includecstdio#includecstring#includesignal.h#includeunistd.hvoidCreateAndStartTimer(unsignedintwait_seconds){if(wait_seconds0)return;timer_t timerid;structsigeventsev;structitimerspecits;// Create the timersev.sigev_notifySIGEV_SIGNAL;sev.sigev_signoSIGTERM;sev.sigev_value.sival_ptrtimerid;if(timer_create(CLOCK_MONOTONIC,sev,timerid)-1){fprintf(stderr,Failed to create timer, will continue running.\n);return;}// Start the timerits.it_value.tv_secwait_seconds;its.it_value.tv_nsec0;its.it_interval.tv_sec0;its.it_interval.tv_nsec0;if(timer_settime(timerid,0,its,NULL)-1){fprintf(stderr,Failed to set timer, will continue running.\n);}}intmain(intargc,char*argv[]){unsignedintwait_seconds0;if(argc!2){fprintf(stderr,Usage: %s time-out-seconds \n,argv[0]);exit(EXIT_FAILURE);}wait_secondsatoi(argv[1]);if(wait_seconds0)CreateAndStartTimer(wait_seconds);while(1){sleep(1);}return0;}以上是最简洁的做法。因为要做的工作就是时间到了杀死本进程因而也没有什么好多做处理的。基本上本文到此就可以结束了。要注意的主要是timer_create(),timer_settime()以及sigevent的用法。man一下基本上就比较清楚了。方法二在有些情况下需要捕获实时信号而在设定实时信号的处理函数时有可能希望暂时屏蔽实时信号待设置完再进行处理。这些都是比较常见的需求。这里以另一个程序来演示实时信号以及屏蔽和去屏蔽信号的做法。// g timer.cpp -lrt#includectime#includecstdlib#includecstdio#includecstring#includesignal.h#includeunistd.h#defineerrExit(msg)do{perror(msg);exit(EXIT_FAILURE);}while(0)#defineSIGSIGRTMINtypedefvoid(*signal_handler_t)(int,siginfo_t*,void*);voidsignal_handler(intsigno,siginfo_t*info,void*context){pid_t myselfgetpid();kill(myself,SIGTERM);}voidset_signal_handler(intsigno,signal_handler_t handler){structsigactionsigaction_info;memset(sigaction_info,0,sizeof(sigaction_info));sigset_t sigset_info;sigemptyset(sigset_info);sigaction_info.sa_handlerNULL;sigaction_info.sa_sigactionhandler;sigaction_info.sa_masksigset_info;sigaction_info.sa_flagsSA_SIGINFO;}voidCreateAndStartTimer(unsignedintwait_seconds){if(wait_seconds0)return;timer_t timerid;structsigeventsev;structitimerspecits;sigset_t mask;set_signal_handler(SIG,signal_handler);// Block timer signal temporarilysigemptyset(mask);sigaddset(mask,SIG);if(sigprocmask(SIG_SETMASK,mask,NULL)-1){errExit(sigprocmask);}// Create the timersev.sigev_notifySIGEV_SIGNAL;sev.sigev_signoSIG;sev.sigev_value.sival_ptrtimerid;if(timer_create(CLOCK_REALTIME,sev,timerid)-1){fprintf(stderr,Failed to create timer, will continue running.\n);return;}// Start the timerits.it_value.tv_secwait_seconds;its.it_value.tv_nsec0;its.it_interval.tv_sec1;its.it_interval.tv_nsec0;if(timer_settime(timerid,0,its,NULL)-1){fprintf(stderr,Failed to set timer, will continue running.\n);}// Unblock timer signalif(sigprocmask(SIG_UNBLOCK,mask,NULL)-1){errExit(sigprocmask);}}intmain(intargc,char*argv[]){unsignedintwait_seconds0;if(argc!2){fprintf(stderr,Usage: %s time-out-seconds \n,argv[0]);exit(EXIT_FAILURE);}wait_secondsatoi(argv[1]);if(wait_seconds0)CreateAndStartTimer(wait_seconds);while(1){sleep(10);}exit(EXIT_SUCCESS);}方法三最后还有一种土办法可以不用timer. 那就是再开一个线程在其中写一个 while (true) 的循环循环体中 sleep(1). 每次醒来的时候检查一下时间过去了多久。如果时间已经超过了设定的时限那么就获得本进程的pid并且发送 SIGTERM 信号给本进程。这个代码就不列在这里了可以参见 ThreadTimeKiller(END)