登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 入门基础 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

后台模拟多任务的实现
发表日期:2007-01-17作者:[转贴] 出处:  

记得以前学过 Win9x/NT的利用时间片轮转实现了多任务,而其中又用时钟中断作为任务调度的方法。每次发生时钟中断,多任务系统就自动保存当前任务的各种状态,标志到状态表。更新任务时间表,判断所有任务的状态:激活/挂起/死锁了。然后利用一定的算法找出最迫切需要运行的进程,接着读取并恢复它的状态表,利用一个jmp或者iret指令完成调度切换。

在DOS下是单任务系统,而编程常常需要多任务的功能,诸如条色板流动,MIDI播放,WAVE混音。等等需要和主程序同时运行的进程。于是就有人开始设计使DOS进程支持多任务的程序,然而写成前面所说的那种未免太大动干戈了,许多任务并不会占用许多时间,如MIDI播放,TSR检测,色彩流动等每个循环只是占用及少的时间,于是我们的代码可以简化了,我们模拟的多任务系统可以简化到按一定频率激活进程,并且要求进程自动放弃时间片,否则就overfollow,如此实现是很简单的:

首先设置中断服务程序MyInt8()并保存老的中断,然后编程系统时钟芯片把时钟滴答从18.2次/秒改
成200次/秒(见SetTimerRate()),完成初始化(见lt_install_timer())。每次发生中断是服务程序 MyInt8()就扫描任务表,统计出各个任务需要运行多少次,然后再分别运行。注意一定要先统计再运行我以前忽略这点,因为有些进程会自己将自己remove,如果不先统计而是边运行边更新时间表的话由于remove后speed变为0而会死循环造成 overfollow。中断服务程序结束时要判断是否到运行老的Int8的时间,否则就用写0x20到端口0x20发送中断结束信号。如此反复运行达到了我们期望的目的。

可以看出我的代码接口是和Allegro一样的,因为大家一看就知道具体用法了。但我并没有copy Allegro的方法,因为我开始写后台服务程序时还不知道Allegro是什么,下面是代码:LTIMER.H LTIMER.CPP TIMEDEMO.CPP,这里有它们打包了的源程序


第一部分:
// 后台时钟系统控制程序,
// 提供16个不同速率的进程同时运行,中心控制程序分时定义为1/200
// 秒一个时间片,程序在 Borland C++3.1编译并通过,
// 
// Copyright (c) 1997,2000 Newbird, written by Skywind
// 请访问无名鸟工作室 http://newbird.126.com
//

#ifndef LTIMER_H
#define LTIMER_H

#define TRUE 1
#define FALSE 0

#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#define MID(x,y,z) MAX((x), MIN((y), (z)))
#endif


void lt_install_timer(); // 初始化时钟系统
void lt_remove_timer(); // 结束系统
// 如果你不还原,系统会自动在程序结束是还原
long lt_clock(char swit); // 取时钟,参数swit为0,1代表取1.198181Hz 和200Hz的时钟
char lt_install_int_ex(void (*proc)(),long speed); // 设置并激活进程, // speed代表1198181Hz的系统时钟为标准的停顿时间
char lt_install_int(void (*proc)(),long speed); // 设置并激活进程
// speed代表千分之几秒
void lt_remove_int(void (*proc)()); // 结束系统

#endif

第二部分:
// Timer Control
// support 16 processes running in different
// rate and in the same time
//
// Copyright (c) 1997,2000 Newbird, written by Skywind
// for more information please see http://newbird.126.com
//

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include "ltimer.h"
#define MAX_TIMERS 16

void lt_install_timer();
void lt_remove_timer();
long lt_clock(char swit); // 0: 1.19MHz 1:200Hz the same
char lt_install_int_ex(void (*proc)(),long speed);
char lt_install_int(void (*proc)(),long speed);
void lt_remove_int(void (*proc)());

static long tinstall=0,autoexit=0,Timer_Delay=65536L;
static long lt_clock0=0, lt_clock1=0;
short lt_Intr=0x08;

// 进程定义结构
static struct { 
    void ((*proc)()); // 进程指针
   
long speed; // 进程的速度
    long counter; // 计数器
} my_int_queue[MAX_TIMERS+1]; 

// 换算定义
#define TIMERS_PER_SECOND 1193181L
#define SECS_TO_TIMER(x) ((long)(x) * TIMERS_PER_SECOND)
#define MSEC_TO_TIMER(x) ((long)(x) * (TIMERS_PER_SECOND / 1000))
#define BPS_TO_TIMER(x) (TIMERS_PER_SECOND / (long)(x))
#define BPM_TO_TIMER(x) ((60 * TIMERS_PER_SECOND) / (long)(x))
#define LOVE_TIME_SPEED BPS_TO_TIMER(200)

static void interrupt MyInt8(...);
static void interrupt far (*OldInt8)(...);
static void SetTimerRate(unsigned long v);
static int FindProc(void (*proc)());
static void UpdateRate();

// 再进程表中寻找一个与proc匹配的函数指针
// 如果没有找到则返回一个没有分配的进程
static int FindProc(void (*proc)())
{
    int i;
    for (i=0;i<MAX_TIMERS;i++) if (proc==my_int_queue[i].proc) return i;
    i=0; while (my_int_queue[i].proc&&i<MAX_TIMERS) i++; // Find a new space
    my_int_queue[i].speed=my_int_queue[i].counter=0;
    return i;
}

// 删除进程
void lt_remove_int(void (*proc)())
{
    int i=FindProc(proc);
    my_int_queue[i].proc=NULL;
    my_int_queue[i].speed=my_int_queue[i].counter=0;
}

// 启动进程
char lt_install_int_ex(void (*proc)(), long speed)
{
    int i=FindProc(proc);
    my_int_queue[i].proc=proc;
    my_int_queue[i].counter-=my_int_queue[i].speed;
    my_int_queue[i].counter+=speed; my_int_queue[i].speed=speed;
    if (i<MAX_TIMERS) return 1;
    return 0;
}

// 更新时钟服务程序频率
static void UpdateRate()
{
    int i;
    long new_speed=65536L;
    for (i=0;i<MAX_TIMERS;i++)
        if (my_int_queue[i].proc&&my_int_queue[i].speed<new_speed)
            new_speed=my_int_queue[i].speed;
    if (new_speed!=Timer_Delay)
    {
        Timer_Delay=new_speed;
        if (Timer_Delay>65536L) Timer_Delay=65536L;
        SetTimerRate(Timer_Delay);
    }
}

// 以千分之x秒为运行频率启动进程
char lt_install_int(void (*proc)(),long speed)
{
    return lt_install_int_ex(proc,MSEC_TO_TIMER(speed));
}

// 返回系统记录的时钟
long lt_clock(char swit)
{
    if (!tinstall) lt_install_timer();
    if (swit==0) return lt_clock0;
    return lt_clock1;
}

// 中断服务程序
static void interrupt MyInt8(...)
{
    register short i;
    static long old_delay=65536L, old_counter=65536L;
    static short callback[MAX_TIMERS];

    lt_clock0+=Timer_Delay; lt_clock1++; // 更新时钟

    // 统计每个进程需要运行几次
    for (i=0;i<MAX_TIMERS;i++) { 
        callback[i]=0;
        if ((my_int_queue[i].proc) && (my_int_queue[i].speed>0))
        {
            my_int_queue[i].counter-=Timer_Delay;
            while (my_int_queue[i].counter<=0)
            {
                my_int_queue[i].counter+=my_int_queue[i].speed;
                callback[i]++;
            }
        }
    }

    // 实际运行进程。
    for (i=0;i<MAX_TIMERS;i++)
    {
        while(callback[i]>0)
        {
            if (my_int_queue[i].proc) (*my_int_queue[i].proc)();
            callback[i]--;
        }
    }

    // 处理老时钟
    old_counter-=Timer_Delay;
    if (old_counter<=0)
    {
        old_counter+=old_delay;
        if (lt_Intr==0x08) _chain_intr(OldInt8);
    }

    _enable();
    if (lt_Intr==0x08) outportb(0x20,0x20);
}

// 更新服务程序频率
static void SetTimerRate(unsigned long v)
{
    if (v>65536||v==0) v=65536;
    _disable();
    outportb(0x43, 0x34);
    outportb(0x40, v & 0xff);
    outportb(0x40, v >> 8);
    _enable();
    Timer_Delay=v;
}

// 初始化
void lt_install_timer()
{
    int i;
    if (tinstall) return;
    OldInt8=_dos_getvect(lt_Intr);
    _disable();
    _dos_setvect(lt_Intr,MyInt8);
    _enable();
    tinstall=1;
    SetTimerRate(LOVE_TIME_SPEED);
    for (i=0;i<MAX_TIMERS;i++) my_int_queue[i].proc=NULL;
    if (!autoexit) { atexit(lt_remove_timer); autoexit=1; }
}

// 返回服务程序停顿
long lt_report_delay() { return Timer_Delay; }

// 移除中断服务程序并结束
void lt_remove_timer()
{
    if (!tinstall) return;
    tinstall=0;
    _disable();
    _dos_setvect(lt_Intr,OldInt8);
    _enable();
    SetTimerRate(0);
}


这下面就是一个利用整套系统的示例:
// 后台时钟系统控制程序,
// 提供16个不同速率的进程同时运行,中心控制程序分时定义为1/200
// 秒一个时间片,程序在 Borland C++ 10.0编译并通过。
//
// Copyright (c) 1997,2000 Newbird, written by Skywind
// 请访问无名鸟工作室 http://newbird.126.com
//

#include "LTIMER.CPP"

#include <stdio.h>
#include <conio.h>

char *VideoBuf=(char *)0xb8000000L;
void process1();
void process2();
void process3();

long delay_timer[3]={ 50, 200, 1000 };

void main()
{
   
lt_install_timer();
    printf("Timer system installed\n");
    lt_install_int(process1,delay_timer[0]);
    lt_install_int(process2,delay_timer[1]);
    lt_install_int(process3,delay_timer[2]);
    printf("Setup 3 process at the different speed\n");
    printf("press any key to stop process1\n");
    getch();
    lt_remove_int(process1);
    printf("press any key to stop process2\n");
    getch();
    lt_remove_int(process2);
    printf("press any key to stop all process and quit\n");
    getch();
    lt_remove_timer(); // this action will stop all the process first
    printf("Good bye, Timer Demo written by Skywind\n");
    printf("For more information please see NewBird Group http://newbird.126.com\n");
}

void process1()
{
    static int counter='A';
    VideoBuf[80]=counter;
    if (++counter>'Z') counter='A';
}
void process2()
{
    static int counter='a';
    VideoBuf[82]=counter;
    if (++counter>'z') counter='a';
}
void process3()
{
    static int counter='0';
    VideoBuf[84]=counter;
    if (++counter>'9') counter='0';
}

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 后台模拟多任务的实现

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00197