下面附上我的源代码下载连接,压缩包中的mtm.cpp是一个多任务管理器的演示,该程序演示20个分配给不同时间片的任务的同时处理,希望大家多多回帖,多多提意见,指正错误,谢谢阿。。
[attach]2926[/attach]
源代码: /* 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); }
/* 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; }