| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 636 人关注过本帖
标题:[原创]一个调度类
只看楼主 加入收藏
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
 问题点数:0 回复次数:3 
[原创]一个调度类
大家是否在为C语言无法同时处理多个任务而感到烦恼,最近在研究《最终幻想》ATB战斗系统中突然有所感悟,C语言是可以处理多个任务的,关键在于时间的分配。小弟没有学过数据结构,更没有学过操作系统原理,不知道称之为“调度”是不是合适,如果不对,大家积极给与指正,谢谢。因为与类相关,所以要用TC3.0编译(大大不要移我的帖子啊,C++板块实在没有人气,所以

下面附上我的源代码下载连接,压缩包中的mtm.cpp是一个多任务管理器的演示,该程序演示20个分配给不同时间片的任务的同时处理,希望大家多多回帖,多多提意见,指正错误,谢谢阿。。

[attach]2926[/attach]
2005-08-21 21:54
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
得分:0 

源代码: /* Dispatch.h 接口文件 */ #ifndef __DISPATCH_H #define __DISPATCH_H

#include "Dispatch.cpp"

#endif /* Dispatch.cpp */ // Processing message every 1000 ms #define MSG_WAITING_TIME 1000

// Common delay time #define COMMON_DELAY 1

// Message detail

// <msgAddSlice> means a new created clock slice structure incomes // for requiring a adding operation.

// <msgKickSlice> means to kick a slice by user operation, this message // requiring a removing operation.

// <msgTurnOff> means to turn off the dispatch management, this message // requiring a quiting operation.

// <msgUser> means a user defined message to process user function

typedef enum { msgAddSlice, msgKickSlice, msgTurnOff, msgUser } clock_msg;

// clock slice for a single task struct clock_slice { // id=0 is message queue default processing interval. unsigned int id,delay_time; unsigned long tick; struct clock_slice *next,*prev; };

typedef union { // the variable id holds the clock slick id which will be removed. unsigned int id,ms; } msg_data;

// message members in message queue wait for processing struct msg_queue { clock_msg msg; msg_data data; struct msg_queue *next,*prev; };

class Dispatch { public: Dispatch(); Dispatch(unsigned int ms);

// Start dispatching void StartDispatch(void); // Add time slice void AddSlice(unsigned int ms); // Kick time slice void KickSlice(unsigned int id);

virtual clock_msg OnClockSliceExecute(unsigned int id,msg_data *d) {};

~Dispatch(); private: struct clock_slice *NewSliceMember(unsigned int ms); struct msg_queue *NewQueueMember(clock_msg msg); void AddMessage(clock_msg msg,msg_data d); void ProcessMessage(void); void free_clock_list(void); void free_msg_queue(void); protected: struct clock_slice *clock_head,*clock_tail; struct msg_queue *que_head,*que_tail; unsigned int sl_count; };

Dispatch::Dispatch() { clock_head=(struct clock_slice *)malloc(sizeof(struct clock_slice)); if(!clock_head) { printf("Not enough!\n"); exit(EXIT_FAILURE); } clock_head->id=0; clock_head->delay_time=MSG_WAITING_TIME; clock_head->tick=0; clock_tail=clock_head; // Round the list clock_tail->next=clock_tail; clock_tail->prev=clock_head; sl_count=1; // Initalize queue que_head=que_tail=NULL; }

Dispatch::Dispatch(unsigned int ms) { if(ms < 100) Dispatch(); else { Dispatch(); // change the delay_time; clock_head->delay_time=ms; } }

Dispatch::~Dispatch() { free_clock_list(); free_msg_queue(); sl_count=0; }

struct clock_slice *Dispatch::NewSliceMember(unsigned int ms) { if(ms < 100) return NULL;

struct clock_slice *sl=NULL; sl=(struct clock_slice *)malloc(sizeof(struct clock_slice)); if(!sl) { printf("Not enough memory!\n"); exit(EXIT_FAILURE); } sl->id=sl_count; sl->delay_time=ms; sl->tick=0; sl->next=sl->prev=NULL; return sl; }

struct msg_queue *Dispatch::NewQueueMember(clock_msg msg) { if(msg == msgTurnOff) return NULL; struct msg_queue *mqm=NULL; mqm=(struct msg_queue *)malloc(sizeof(struct msg_queue)); if(!mqm) { printf("Not enough memory!\n"); exit(EXIT_FAILURE); } mqm->msg=msg; mqm->next=mqm->prev=NULL; return mqm; }

void Dispatch::AddMessage(clock_msg msg,msg_data d) { struct msg_queue *mqm=NewQueueMember(msg); if(mqm) { mqm->data=d; if(!que_head) { que_head=mqm; que_tail=que_head; } else { que_tail->next=mqm; mqm->prev=que_tail; que_tail=que_tail->next; } } }

void Dispatch::AddSlice(unsigned int ms) { struct clock_slice *sl=NewSliceMember(ms); if(sl) { clock_tail->next=sl; sl->prev=clock_tail; clock_tail=clock_tail->next; // Round the list clock_tail->next=clock_head; sl_count++; } }

void Dispatch::KickSlice(unsigned int id) { if(id) { struct clock_slice *p=clock_head->next,*bk=NULL,*bk1=NULL; for(;p->id!=id;p=p->next) ; bk=p->next; bk1=p; p=p->prev; p->next=bk; bk->prev=p; free(bk1); sl_count--; } }

void Dispatch::ProcessMessage(void) { // First in First Out, so process the head first struct msg_queue *p=que_head,*bk=NULL; while(p) { if(p->msg == msgAddSlice) AddSlice(p->data.ms); else if(p->msg == msgKickSlice) KickSlice(p->data.id); // Processing Message One by One bk=p->next; free(p); p=bk; } que_head=que_tail=NULL; }

void Dispatch::free_clock_list(void) { struct clock_slice *p=clock_head,*bk=NULL; clock_head->prev=NULL; clock_tail->next=NULL; while(p) { bk=p->next; free(p); p=bk; } clock_head=clock_tail=NULL; }

void Dispatch::free_msg_queue(void) { struct msg_queue *p=que_head,*bk=NULL; while(p) { bk=p->next; free(p); p=bk; } que_head=que_tail=NULL; }

void Dispatch::StartDispatch(void) { if(!clock_head) return ; struct clock_slice *p=clock_head; clock_msg msg; msg_data d; do { delay(COMMON_DELAY); if(p->tick < CLK_TCK*(p->delay_time / 100)) { p->tick++; p=p->next; continue; } if(!p->id) { // When id=0, processing message ProcessMessage(); p->tick=0; continue; } else { msg = OnClockSliceExecute(p->id,&d); if(msg == msgTurnOff) break; else if(msg == msgAddSlice || msg == msgKickSlice) // Add message to the queue and wait for processing AddMessage(msg,d); // Reset tick p->tick=0; } p=p->next; } while(1); }


我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2005-08-21 21:57
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
得分:0 

/* MTM.cpp 多任务管理与执行演示 */ // Sample for multiple task management and execution // Programmed by yuki, 2005-08-21

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <time.h> #include <dos.h> #include <bios.h>

#include "dispatch.h"

#define MAX_TASK_COUNT 20 #define KEY_ESC 0x11b

// static constant static unsigned char x=1,y=2; static unsigned char taskProgress[MAX_TASK_COUNT]={0};

// inherit class class taskMgr : public Dispatch { public: taskMgr() {}; clock_msg OnClockSliceExecute(unsigned int id,msg_data *d); };

clock_msg taskMgr::OnClockSliceExecute(unsigned int id,msg_data *d) { int key=0;

if(bioskey(1)) { key=bioskey(0); // Press esc to exit if(key == KEY_ESC) return msgTurnOff; }

gotoxy(x,y+id); cprintf("%s %c %3d% ","Task",id+'A'-1,++taskProgress[id-1]); // Task executing complete, remove the time slice if(taskProgress[id-1] == 100) { d->id=id; cprintf("Complete "); if(id == MAX_TASK_COUNT) { register int i; // Clean the row for(i=1;i<80;i++) { gotoxy(i,25); putch(0x20); } gotoxy(1,25); cprintf("All taskes is completed! Please enter any key to continue."); getch(); // Kick completed slice to get speed higher return msgTurnOff; } return msgKickSlice; } cprintf("Incomplete"); return msgUser; }

int main(void) { clrscr(); register int i; char buf[32]="Press esc to exit . . ."; taskMgr tm;

gotoxy(80-strlen(buf),25); cprintf("%s",buf); // Create task for(i=0;i<MAX_TASK_COUNT;i++) { taskProgress[i]=0; tm.AddSlice((i+1)*100); } // Start task management and executing operation tm.StartDispatch(); clrscr(); printf("Multiple task management, programmed by yuki\n"); printf("Have a nice day, bye bye!\n"); getch(); return 0; }


我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2005-08-21 21:58
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
得分:0 
修正一个效率错误,请大家找到NewSliceMember()函数,将第一个if(ms&lt;100) return;语句去掉,这个语句会给某些应用造成速度无法提高的问题。

我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2005-08-22 14:47
快速回复:[原创]一个调度类
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017880 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved