最近看Asterisk源码,太久没写代码了,所以根据Asterisk的调度写了个简单的调度。
分享下代码 错误之处 还请指正,欢迎板砖
首先创建一个调度系统的容器,这个容器里面有个队列结构
队列里面是待做事件,事件是由时间驱动,通过比较时间来决定是否执行
sched_create():初始化调度容器 调度队列
sched_queue_get():指定id获取队列中一个事件
sched_add():往调度容器中添加一条事件
sched_del():完成一个事件之后,在事件队列里面删除这个事件,需要注意头结点与尾结点的删除
sched_run():监视事件队列,调度的核心就是循环跑队列
callback 是个回调函数,用来处理指定的事件
最好结合线程池,网络,数据库这些,就可以搞个网络服务器了,时间关系,这些还没加上,下次再完善吧
/*
*
* DataStruct:
* sched_context
* |
* |
* sched_queue
* / \
* / \
* head tail
* / \
* sched_1->sched_2->..->sched_n->NULL
*/
#include <stdio.h>
//#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#define LIST_TEMPLATE(structtype, datatype)\
struct structtype { \
struct structtype *next;\
datatype *data; \
}
#define LIST_QUEUE_TEMPLATE(structtype) \
struct structtype { \
struct structtype *head; \
struct structtype *tail; \
struct structtype *next; \
int id; \
}
struct queue {
struct sched *head;
struct sched *tail;
};
struct sched_context {
unsigned int eventcnt; // create ids
unsigned int schedcnt; // the number of current schedule
struct queue *sched_queue;
// pthread_mutex_t sched_mutex;
void *data;
};
typedef int (*callback)(void *data);
struct sched {
int id;
struct timeval time;
int when;
callback cb;
void *data;
struct sched *next;
};
int sched_add(struct sched_context *schedule, int when, callback cb, void *data);
int sched_del(struct sched_context *schedule, int sched_id);
struct sched_context* sched_create(void);
int sched_run(struct sched_context *schedule);
struct sched *sched_queue_get(struct sched_context *schedule, int id);
struct sched_context* sched_create(void)
{
struct sched_context *con = NULL;
con = (struct sched_context *)malloc(sizeof(*con));
if ( !con ){
printf("create schedule context error!\n");
return con;
}
con->eventcnt = 0;
con->schedcnt = 0;
con->data = NULL;
con->sched_queue = (struct queue *)malloc(sizeof(struct queue));
if ( !con->sched_queue ){
printf("initialize queue error!\n");
free(con);
con = NULL;
return NULL;
}
con->sched_queue->head = NULL;
con->sched_queue->tail = NULL;
return con;
}
struct sched *sched_queue_get(struct sched_context *schedule, int id)
{
struct sched *cur = NULL;
struct queue *pos = NULL;
if ( !schedule )
{
printf("schedule is NULL\n");
return NULL;
}
pos = schedule->sched_queue;
if ( !pos )
{
printf("Something must be wrong in the sched_queue\n");
return NULL;
}
for ( cur = pos->head; cur; cur = cur->next )
{
if ( cur->id == id )
{
return cur;
}
}
printf("id is not in the queue\n");
return NULL;
}
int sched_add(struct sched_context *schedule, int when, callback cb, void *data)
{
struct sched *add = NULL;
struct queue *q = NULL;
if ( !schedule )
{
printf("The param schedule is NULL \n");
return -1;
}
add = (struct sched *)malloc(sizeof(*add));
add->id = ++schedule->eventcnt;
add->when = when;
add->cb = cb;
add->data = data;
add->next;
gettimeofday(&add->time, NULL);
add->time.tv_sec += when;
schedule->schedcnt++;
q = schedule->sched_queue;
if ( !q )
{
printf("Something must be wrong in schedule->queue\n");
return -1;
}
if ( !q->head )
{
q->head = add;
q->tail = add;
}
else{
struct sched *s = NULL;
s = q->head;
while ( s->next )
s = s->next;
s->next = add;
q->tail = add;
}
return add->id;
}
int sched_del(struct sched_context *schedule, int sched_id)
{
struct sched *del = NULL, *pre;
if ( !schedule && !schedule->sched_queue )
{
printf("The param schedule is NULL \n");
return -1;
}
pre = schedule->sched_queue->head;
for ( del = schedule->sched_queue->head; del; del = del->next )
{
if ( del->id == sched_id )
{
pre->next = del->next;
if ( !del->next )
schedule->sched_queue->tail = pre;
if ( del == schedule->sched_queue->head )
schedule->sched_queue->head = del->next;
free(del);
}
pre = del;
}
return 0;
}
int sched_run(struct sched_context *schedule)
{
struct queue *q = NULL;
struct sched *s = NULL;
struct timeval t;
if ( !schedule || !
schedule->sched_queue )
{
printf("The param schedule is NULL \n");
return -1;
}
q = schedule->sched_queue;
for (; ;)
{
s = q->head;
for (; s; s = s->next )
{
gettimeofday(&t, NULL);
if ( t.tv_sec >= s->time.tv_sec )
{
s->cb(s->data);
sched_del(schedule, s->id);
schedule->schedcnt--;
// sleep(2);
}
}
}
}
int sched1(void *data)
{
printf("sched1 say hello\n");
return 0;
}
int sched2(void *data)
{
printf("sched2 say hello\n");
return 0;
}
int sched3(void *data)
{
printf("sched3 say hello\n");
return 0;
}
struct sched_context *schedule;
int main(int argc, char **argv)
{
schedule = sched_create();
if ( !schedule )
return 1;
sched_add(schedule, 5, sched1, NULL);
sched_add(schedule, 10, sched2, NULL);
sched_add(schedule, 15, sched3, NULL);
sched_run(schedule);
return 0;
}