背景
客户端和服务器采用异步请求/回复模式,客户端需要为每个API设置超时回调处理。方案
采用posix定时器。posix定时器
主要接口函数:
1)创建一个定时器:
int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
2)启动一个定时器:
timer_create()所创建的定时器并未启动。要将它关联到一个到期时间以及启动时钟周期,可以使用timer_settime()。
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspect *ovalue);
3)获得一个活动定时器的剩余时间:
int timer_gettime(timer_t timerid,struct itimerspec *value);
4)删除一个定时器:
int timer_delete (timer_t timerid);
接口函数的参数解释,请通过man命令查看。
实例
timeout-handler.h
/***********************************************************
*
* File name : timeout-handler.h
* Version : 1.0
* Description: posix real timer test
*
************************************************************/
#ifndef _TIMEOUT_HANDLER_H_
#define _TIMEOUT_HANDLER_H_
#include <signal.h>
#include <time.h>
#define MAX_TIMER_NUM 32
#define SIGNUM_RT_TIMER (SIGRTMIN + 2)
typedef enum
{
CLIENT_MIN_TIMER_ID,
HEART_BEAT_TIMER_ID,
REGISTER_TIMER_ID,
LOGIN_TIMER_ID,
BIND_TIMER_ID,
UNBIND_TIMER_ID,
CLIENT_MAX_TIMER_ID
} CLIENT_TIMER_ID;
typedef struct
{
char *name; /* API name */
int count; /* timeout times */
int expires; /* general 5s */
timer_t timer; /* timer id */
void (*cb)(void); /* call back */
} REQUEST_TIMEOUT_OBJECT;
/* initialize request timeout times */
int initReqTimeoutCount(int idx);
/* start or stop timer */
int clientTimerSwitch(int idx, int type);
/* delete timer */
int clientDeleteTimer(timer_t timer_id);
/* delete all timer */
int clientDeleteAllTimer();
/* init timer */
int initClientTimer();
#endif
timeout-handler.c
/***********************************************************
*
* File name : timer-handler.c
* Version : 1.0
* Description: timeout handler
*
************************************************************/
#include <string.h>
#include <errno.h>
#include "client-timer.h"
#include "timeout-handler.h"
timer_t timers[MAX_TIMER_NUM] = {0};
static void clientHeartBeatExpired();
static void clientRegisterExpired();
static void clientLoginExpired();
static void clientBindExpired();
static void clientUnbindExpired();
REQUEST_TIMEOUT_OBJECT gReqTimeoutObj[] =
{
[CLIENT_MIN_TIMER_ID] =
{
.name = "min timer",
.count = 0,
.expires = 5,
.cb = NULL,
.timer = 0
},
[HEART_BEAT_TIMER_ID] =
{
.name = "heartbeat",
.count = 0,
.expires = 3,
.cb = clientHeartBeatExpired,
.timer = 0
},
[REGISTER_TIMER_ID] =
{
.name = "register",
.count = 0,
.expires = 5,
.cb = clientRegisterExpired,
.timer = 0
},
[LOGIN_TIMER_ID] =
{
.name = "login",
.count = 0,
.expires = 7,
.cb = clientLoginExpired,
.timer = 0
},
[BIND_TIMER_ID] =
{
.name = "bind",
.count = 0,
.expires = 2,
.cb = clientBindExpired,
.