用C实现的工作线程定时器方式
我有一个工作线程,从管道得到的工作。事情是这样的。
I have a worker thread that gets work from pipe. Something like this
void *worker(void *param) {
while (!work_done) {
read(g_workfds[0], work, sizeof(work));
do_work(work);
}
}
我需要实现在同一个线程1秒计时器做一些簿记有关的工作。以下是我在心中已经:
I need to implement a 1 second timer in the same thread do to some book-keeping about the work. Following is what I've in mind:
void *worker(void *param) {
prev_uptime = get_uptime();
while (!work_done) {
// set g_workfds[0] as non-block
now_uptime = get_uptime();
if (now_uptime - prev_uptime > 1) {
do_book_keeping();
prev_uptime = now_uptime;
}
n = poll(g_workfds[0], 1000); // Wait for 1 second else timeout
if (n == 0) // timed out
continue;
read(g_workfds[0], work, sizeof(work));
do_work(work); // This can take more than 1 second also
}
}
我使用的系统正常运行时间,而不是系统时间,因为虽然这线程在运行系统时可以得到改变。我不知道是否有其他更好的方法来做到这一点。我不想考虑使用其他的线程。使用报警()
不是因为它已经用在同一进程中另一个线程的选项。这是在Linux环境中得到实现。
I am using system uptime instead of system time because system time can get changed while this thread is running. I was wondering if there is any other better way to do this. I don't want to consider using another thread. Using alarm()
is not an option as it already used by another thread in same process. This is getting implemented in Linux environment.
我已经找到了更好的办法,但它使用的 timerfd_create()系统调用。它负责系统时间的改变。以下是可能的伪code:
I have found a better way but it is Linux specific using timerfd_create() system call. It takes care of system time change. Following is possible psuedo code:
void *worker(void *param) {
int timerfd = timerfd_create(CLOCK_MONOTONIC, 0); // Monotonic doesn't get affected by system time change
// set timerfd to non-block
timerfd_settime(timerfd, 1 second timer); // timer starts
while (!work_done) {
// set g_workfds[0] as non-block
n = poll(g_workfds[0] and timerfd, 0); // poll on both pipe and timerfd and Wait indefinetly
if (timerfd is readable)
do_book_keeping();
if (g_workfds[0] is readable) {
read(g_workfds[0], work, sizeof(work));
do_work(work); // This can take more than 1 second also
}
}
}
这似乎更清洁和阅读()
在 timerfd
返回的情况下,经过加时赛 do_work()
时间长这是相当有用,因为 do_book_keeping()
期望得到所谓的每一秒。
It seems cleaner and read()
on timerfd
returns extra time elapsed in case do_work()
takes long time which is quite useful as do_book_keeping()
expects to get called every second.