用C实现的工作线程定时器方式 [英] ways of implementing timer in worker thread in C

查看:115
本文介绍了用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.

这篇关于用C实现的工作线程定时器方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆