现在的位置: 首页 > 综合 > 正文

简单的调度

2013年12月04日 ⁄ 综合 ⁄ 共 3986字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.