標籤:style blog http io os 使用 ar for sp
1.使用14號訊號SIGALRM,調用alarm函數
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>void handle(int signum){ printf("hello\n");}int main(int argc, const char *argv[]){ signal(SIGALRM, handle); while(1) { alarm(3); sleep(3); } return 0;}
//每隔3秒向自身發送一個SIGALRM訊號,signal收到 SIGALRM訊號後調用handle進行處理
--》alarm只能精確到秒
2.setitimer -->也是通過向自身發送訊號進行處理的,不過可以精確到毫妙層級
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.
ITIMER_VIRTUAL decrements only when the process is executing, and delivers
SIGVTALRM upon expiration.
ITIMER_PROF decrements both when the process executes and when the system is
executing on behalf of the process. Coupled with ITIMER_VIR-
TUAL, this timer is usually used to profile the time spent by
the application in user and kernel space. SIGPROF is delivered
upon expiration.
struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
--》3種模式產生3中不同的訊號,使用方法類似
在該例子中,每隔一秒發出一個SIGALRM,每隔0.5秒發出一個SIGVTALRM訊號:#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <time.h>#include <sys/time.h>int sec;void sigroutine(int signo){switch (signo){case SIGALRM:printf("Catch a signal -- SIGALRM \n");signal(SIGALRM, sigroutine);break;case SIGVTALRM:printf("Catch a signal -- SIGVTALRM \n");signal(SIGVTALRM, sigroutine);break;}fflush(stdout);return;}int main(){struct itimerval value, ovalue, value2; //(1)sec = 5;printf("process id is %d\n", getpid());signal(SIGALRM, sigroutine);signal(SIGVTALRM, sigroutine);value.it_value.tv_sec = 1;value.it_value.tv_usec = 0;value.it_interval.tv_sec = 1;value.it_interval.tv_usec = 0;setitimer(ITIMER_REAL, &value, &ovalue); //(2)value2.it_value.tv_sec = 0;value2.it_value.tv_usec = 500000;value2.it_interval.tv_sec = 0;value2.it_interval.tv_usec = 500000;setitimer(ITIMER_VIRTUAL, &value2, &ovalue);for(;;);}
3.timerfd_create timerfd_settime -->通過時間設定fd可讀,然後通過select輪詢,調用處理函數
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/timerfd.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0)int main(int argc, const char *argv[]){ struct itimerspec time; time.it_value.tv_sec = 5; time.it_interval.tv_sec = 2; int timerfd = timerfd_create(CLOCK_REALTIME, 0); if(timerfd == -1) ERR_EXIT("timerfd_create"); if(timerfd_settime(timerfd, 0, &time, NULL) == -1) ERR_EXIT("timerfd_settime"); fd_set read1, ready; FD_ZERO(&read1); FD_SET(timerfd, &read1); char buf[1024]; struct timeval time_select; while(1) { time_select.tv_sec = 3;//必須定義在while內部 time_select.tv_usec = 11; ready = read1; int nready = select(timerfd + 1, &ready, NULL, NULL, &time_select);//設定為一直阻塞 if(nready == -1) ERR_EXIT("select"); else if(nready == 0) printf("timeout"); else { if(-1 == read(timerfd, buf, sizeof buf)) { printf("%s\n", strerror(errno));//列印錯誤資訊 ERR_EXIT("read"); } printf("come\n"); } } return 0;}
4.直接使用select -->精確到毫秒層級
int msSleep(long ms) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = ms; return select(0, NULL, NULL, NULL, &tv);}
其他資料:
http://www.cppblog.com/CppExplore/archive/2008/04/02/46111.html
linux中使用定時器