最近看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; }