C可终止定时器

由于已经实现过C++的版本,这篇文章就不展开论述实现的原理

该定时器利用pthread_cond_timedwait方法实现了定时器的中断,具体原理可转至C++可终止定时器.

代码实现

timer.h

#ifndef __TIMER_H__
#define __TIMER_H__

#include <pthread.h>

typedef void (*callback) (void);
typedef struct timer_t {
        pthread_t tid;
        pthread_cond_t cond;
        pthread_mutex_t mutex;
        int status;
        callback cbk;
        long delay_sec;
} timer_t;


#define TIMER_STATUS_UNINIT 0
#define TIMER_STATUS_START 1
#define TIMER_STATUS_STOP 2

int timer_init(struct timer_t *timer);

int timer_start(struct timer_t *timer, long delay_sec, callback cbk);

int timer_stop(struct timer_t *timer);

int timer_destroy(struct timer_t *timer);

int timer_status(struct timer_t *timer);
#endif

timer.c

#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>
#include "timer.h"

static void* thread_routine(void *args)
{
    struct timer_t *timer = (struct timer_t *)args;
    printf("start timer, tid:%d delay:%ld sec\n", (int)timer->tid, timer->delay_sec);
    struct timespec abstime;
    struct timeval now;
    gettimeofday(&now, NULL);
    abstime.tv_sec = now.tv_sec + timer->delay_sec;
    abstime.tv_nsec = 0;
    pthread_mutex_lock(&timer->mutex);
    timer->status = TIMER_STATUS_START;
    int ret = pthread_cond_timedwait(&timer->cond, &timer->mutex, &abstime);
    if (ret == ETIMEDOUT) {
        printf("tid:%d timer has reached, exec callback\n", (int)timer->tid);
	timer->cbk();
    } else {
	printf("tid:%d timer has aborted, stop timer\n", (int)timer->tid);
    }
    timer->status = TIMER_STATUS_STOP;
    pthread_mutex_unlock(&timer->mutex);

    return NULL;
}

int timer_init(struct timer_t *timer)
{
    if (NULL == timer) {
	printf("timer is NULL\n");
	return -1;
    }
    memset(timer, 0, sizeof(struct timer_t));
    pthread_mutex_init(&timer->mutex, NULL);
    pthread_cond_init(&timer->cond, NULL);
    timer->status = TIMER_STATUS_UNINIT;
    return 0;
}

int timer_start(struct timer_t *timer, long delay_sec, callback cbk)
{
    if (NULL == timer) {
	printf("timer is NULL\n");
	return -1;
    }
    if (timer->status != TIMER_STATUS_UNINIT) {
        printf("timer status invalid, check status! (%d)\n", timer->status);
        return -1;
    }
    timer->cbk = cbk;
    timer->delay_sec = delay_sec;
    int ret = pthread_create(&timer->tid, NULL, thread_routine, timer);
    if (ret == -1) {
        perror("pthread_create");
        return -1;
    }
    return 0;
}

int timer_stop(struct timer_t *timer)
{
    if (NULL == timer) {
        printf("timer is NULL\n");
        return -1;
    }
    pthread_mutex_lock(&timer->mutex);
    pthread_cond_signal(&timer->cond);
    pthread_mutex_unlock(&timer->mutex);
    return 0;
}

int timer_destroy(struct timer_t *timer)
{
    if (NULL == timer) {
	printf("timer is NULL\n");
        return -1;
    }
    timer_stop(timer);
    pthread_join(timer->tid, NULL);
    return 0;
}

int timer_status(struct timer_t *timer)
{
    if (NULL == timer) {
	printf("timer is NULL \n");
        return -1;
    }
    return timer->status;
}

测试代码main.c

#include "timer.h"
#include <stdio.h>
#include <unistd.h>

void test()
{
    printf("hello world!\n");
}
int main()
{
    struct timer_t timer;
    if (timer_init(&timer) == -1) {
        printf("timer init fail! check reason\n");
        return -1;
    }

    long delay_sec = 0, wait_sec = 0;
    printf("input delay_sec:");
    scanf("%ld", &delay_sec);

    printf("input wait_sec:");
    scanf("%ld", &wait_sec);
    if (timer_start(&timer, delay_sec, test) == -1) {
        printf("timer start fail! check reason\n");
        return -1;
    }

    for (int i = 0; i < wait_sec; ++i) {

        printf("current timer status:");
        if (timer.status == TIMER_STATUS_UNINIT)
            printf("uninit\n");
        else if (timer.status == TIMER_STATUS_START)
            printf("running\n");
        else
            printf("stop\n");
        sleep(1);
    }


    if (timer_stop(&timer) == -1) {
        printf("timer stop fail! check reason\n");
        return -1;
    }

    if (timer_destroy(&timer) == -1) {
        printf("timer destroy fail! check reason\n");
        return -1;
    }

    return 0;
}

运行效果:

	定时5秒,在第3秒取消定时器效果
input delay_sec:5
input wait_sec:3
current timer status:uninit
start timer, tid:236675072 delay:5 sec
current timer status:running
current timer status:running
tid:236675072 timer has aborted, stop timer

//符合预期效果,回调函数没有被执行
定时5秒,在第6秒取消定时器
input delay_sec:5
input wait_sec:6
current timer status:uninit
start timer, tid:4632576 delay:5 sec
current timer status:running
current timer status:running
current timer status:running
current timer status:running
tid:4632576 timer has reached, exec callback
hello world!
current timer status:stop
//符合预期效果,回调函数被执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值