freebsd/mac os x timer的实现

因为timer_create在mac os x下边并没有实现,所以

    void ErrorManager::threadFun()
    {
        HANDLE hTimer;
        LARGE_INTEGER li;
        hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
        const int nTimerUnitsPerSecond = 10000000;
        li.QuadPart = -(5 * nTimerUnitsPerSecond);

        HANDLE handles[] = { hTimer, hQuitEvent_ };
        while (!quit_) {
            SetWaitableTimer(hTimer, &li, 0,
                NULL, NULL, FALSE);
            auto result = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
            if (result == WAIT_OBJECT_0) {
                client_->queueCheckTimeoutTask();
            } else if (result == WAIT_OBJECT_0 + 1) {
                break;
            }
        }
        CloseHandle(hTimer);
    }

    void ErrorManager::quit()
    {
        quit_ = true;
        SetEvent(hQuitEvent_);
    }

像以上这种windows下的timer代码并不是很容易实现,虽然我们都知道一般os kernel都会有原生的timer list,在rtc中断时候内核会处理,比如讲linux内核实现的posix timer就是这么处理的,但是freebsd/mac os x是没有的,相同的功能最后还是需要kqueue这种看上去比较重量级的东西来实现。

#include <stdio.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>

static void output_time()
{
	time_t tick = time(NULL);
	struct tm atm;
	localtime_r(&tick, &atm);
	printf("current time %02d:%02d:%02d\n", atm.tm_hour, atm.tm_min, atm.tm_sec);
}

int main()
{
	int kq = kqueue();
	if (kq < 0) {
		perror("create kqueue failed");
		return -1;
	}
	umask(0);
	if (mknod("keke", S_IFIFO | 0666, 0) < 0) {
		perror("create named pipe failed");
		return -1;
	}
	puts("mknod succeeded");
	int fp = open("keke", O_RDONLY | O_NONBLOCK);
	if (fp < 0) {
		perror("failed to open named pipe\n");
		return -1;
	}
	struct kevent ev;
	puts("start to set event");
	EV_SET(&ev, fp, EVFILT_READ, EV_ADD, 0, 0, 0);
	if (kevent(kq, &ev, 1, NULL, 0, NULL) < 0) {
	   perror("failed add pipe read event");
	   return -1;
	}
	puts("after to set event");

	output_time();
	EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, 5, 0);
	if (kevent(kq, &ev, 1, NULL, 0, NULL) < 0) {
	   perror("failed add timer event");
	   return -1;
	}
	while (true) {
		struct kevent events[2]; 
		int count =kevent(kq, NULL, 0, events, 2, NULL); 
		if (count > 0) {
			for (int i = 0; i < count; ++i) {
				if (events[i].filter == EVFILT_TIMER) {
					output_time();
				} else if (events[i].filter == EVFILT_READ) {
					puts("break on write event");
					goto done;
				}
			}
		}
	}
done:
	close(fp);
	return 0;
}

这个例子可以随时可以使用pipe来中断,

#include <stdio.h>

int main()
{
	FILE* fp = fopen("keke", "w");
	if (fp == NULL) {
		perror("failed to open named pipe");
		return -1;
	}
	fputs("keke", fp);
	fclose(fp);
	return 1;
}


输出如下:

jcyangzh@fakecoder:~/src/unix/timer$ ./kq
mknod succeeded
start to set event
after to set event
current time 04:34:41
current time 04:34:46
break on write event
jcyangzh@fakecoder:~/src/unix/timer$

refer:http://www.progtown.com/post953316.html#p953316

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值