http://blog.csdn.net/gdutliuyun827/article/details/8470777
看一下timerfd的例子,上代码:
- #include <sys/timerfd.h>
- #include <sys/time.h>
- #include <time.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdint.h> /* Definition of uint64_t */
- #define handle_error(msg) \
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
- void printTime()
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- printf("printTime: current time:%ld.%ld ", tv.tv_sec, tv.tv_usec);
- }
- int main(int argc, char *argv[])
- {
- struct timespec now;
- if (clock_gettime(CLOCK_REALTIME, &now) == -1)
- handle_error("clock_gettime");
- struct itimerspec new_value;
- new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
- new_value.it_value.tv_nsec = now.tv_nsec;
- new_value.it_interval.tv_sec = atoi(argv[2]);
- new_value.it_interval.tv_nsec = 0;
- int fd = timerfd_create(CLOCK_REALTIME, 0);
- if (fd == -1)
- handle_error("timerfd_create");
- if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
- handle_error("timerfd_settime");
- printTime();
- printf("timer started\n");
- for (uint64_t tot_exp = 0; tot_exp < atoi(argv[3]);)
- {
- uint64_t exp;
- ssize_t s = read(fd, &exp, sizeof(uint64_t));
- if (s != sizeof(uint64_t))
- handle_error("read");
- tot_exp += exp;
- printTime();
- printf("read: %llu; total=%llu\n",exp, tot_exp);
- }
- exit(EXIT_SUCCESS);
- }
相关结构体如下:
- struct timespec {
- time_t tv_sec; /* Seconds */
- long tv_nsec; /* Nanoseconds */
- };
- struct itimerspec {
- struct timespec it_interval; /* Interval for periodic timer */
- struct timespec it_value; /* Initial expiration */
- };
代码L25-L29:初始化定时器的参数,初始间隔与定时间隔。
L32:创建定时器fd,CLOCK_REALTIME:真实时间类型,修改时钟会影响定时器;CLOCK_MONOTONIC:相对时间类型,修改时钟不影响定时器。
L35:设置定时器的值。
L44:阻塞等待定时器到期。返回值是未处理的到期次数。比如定时间隔为2秒,但过了10秒才去读取,则读取的值是5。
编译运行:编译时要加rt库(g++ -lrt timerfd.cc -o timerfd)
[root@localhost appTest]# ./timerfd 5 2 10
printTime: current time:1357391736.146196 timer started
printTime: current time:1357391741.153430 read: 1; total=1
printTime: current time:1357391743.146550 read: 1; total=2
printTime: current time:1357391745.151483 read: 1; total=3
printTime: current time:1357391747.161155 read: 1; total=4
printTime: current time:1357391749.153934 read: 1; total=5
printTime: current time:1357391751.157309 read: 1; total=6
printTime: current time:1357391753.158384 read: 1; total=7
printTime: current time:1357391755.150470 read: 1; total=8
printTime: current time:1357391757.150253 read: 1; total=9
printTime: current time:1357391759.149954 read: 1; total=10
[root@localhost appTest]#
第一个参数5为第一次定时器到期间隔,第二个参数2为定时器的间隔,第三个参数为定时器到期10次则退出。程序运行(5+2*10)S退出。
详细信息可以:man timerfd_create
#include <sys/timerfd.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
void printTime()
{
struct timeval tv;
gettimeofday(&tv, NULL);
printf("printTime: current time:%ld.%ld ", tv.tv_sec, tv.tv_usec);
}
int main(int argc, char *argv[])
{
struct timespec now;
if (clock_gettime(/*CLOCK_REALTIME*/CLOCK_MONOTONIC, &now) == -1)
handle_error("clock_gettime");
struct itimerspec new_value;
new_value.it_value.tv_sec = /*now.tv_sec +*/ atoi(argv[1]);
new_value.it_value.tv_nsec =/*now.tv_nsec*/0;
new_value.it_interval.tv_sec = atoi(argv[2]);
new_value.it_interval.tv_nsec = 0;
int fd = timerfd_create(/*CLOCK_REALTIME*/CLOCK_MONOTONIC, 0);
if (fd == -1)
handle_error("timerfd_create");
if (timerfd_settime(fd, /*TFD_TIMER_ABSTIME*/0, &new_value, NULL) == -1)
handle_error("timerfd_settime");
printTime();
printf("timer started\n");
for (uint64_t tot_exp = 0; tot_exp < atoi(argv[3]);)
{
uint64_t exp;
ssize_t s = read(fd, &exp, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("read");
tot_exp += exp;
printTime();
printf("read: %llu; total=%llu\n",exp, tot_exp);
}
exit(EXIT_SUCCESS);
}
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
using namespace std;
int filedes[2];
int main( void )
{
char buf[80];
pid_t pid;
pipe( filedes );
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
fcntl(filedes[1], F_SETFL, O_NONBLOCK);
int epoll_fd = epoll_create(20);
if (epoll_fd!= -1)
fcntl(epoll_fd, F_SETFD, FD_CLOEXEC);
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLET;
ev.data.fd = filedes[0];
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, filedes[0], &ev);
pid=fork();
if (pid > 0)
{
printf( "This is in the father process,here write a string to the pipe.\n" );
char s[] = "Hello world , this is write by pipe.\n";
write( filedes[1], s, sizeof(s) );
while(1){
sleep(10);
epoll_event ev = { 0, { 0 } };
ev.events = EPOLLIN | EPOLLERR | EPOLLET;
ev.data.fd = filedes[0];
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, filedes[0], &ev);
printf( "interrupt send\n" );
}
}
else if(pid == 0)
{
printf( "This is in the child process,here read a string from the pipe.\n" );
while(1){
epoll_event events[128];
int num_events = epoll_wait(epoll_fd, events, 20, 10000);
for (int i = 0; i < num_events; ++i)
{
int fd = events[i].data.fd;
if (fd == filedes[0])
{
printf("interrupt recv\n");
}
}
}
}
close( filedes[0] );
close( filedes[1] );
close(epoll_fd);
//waitpid( pid, NULL, 0 );
return 0;
}