G
N
I
D
A
O
L

协作多任务库

协作多任务库

描述

CMT 是一个轻量级的协作多任务“内核”,具有多任务 C 功能。 该库还提供了其他几个有用的工具:

任务之间的简单消息传递
消息队列
信号灯
定时器
提供用户钩子以通知任务状态更改。

源代码 

这包括完整的源代码、文档和编译库。由于 所有这些代码的性质,这完全是特定于 Borland 的(我使用的是 BC++ 3.1, 2.x 版本也应该可以工作)。如果你想将它与其他编译器一起使用, 您可能需要更改任务管理功能以保存足够的上下文 让它工作。

使用库
库函数和数据结构在“cmtlib.h”中描述, 您必须将其包含在代码中。之后,您通常会创建 您的主要功能中的一些任务是这样的。


#include "cmtlib.h"

void task(void)
{
while (1) {
cmt_pause();
}
}

void main(void)
{
cmt_fork(task,2048);
while (1) {
cmt_pause();
}
}
你刚刚创建的是一个程序,它无休止地运行两个任务,切换 从一个到另一个。cmt_fork() 的第二个参数 (2048) 表示需要 新任务的堆栈大小。一切的关键是 cmt_pause() 函数 切换离开调用方,运行所有其他任务,然后返回到调用方 好像什么都没发生一样。虽然上面的示例是完全有效的代码,但它 没有做那么多。让我们看一个更有趣的例子:


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

void task(void)
{
char *s;
s=cmt_receive();
while (1) {
printf("%s\n",s);
cmt_sleep(1);
}
}

void main(void)
{
cmt_send("one",cmt_fork(task,2048));
cmt_send("two",cmt_fork(task,2048));
cmt_send("three",cmt_fork(task,2048));
while (!kbhit()) {
cmt_pause();
}
getch();
}
那么这是怎么回事呢?我们正在创建同一任务的三个实例, 并通过发送消息给他们每个人不同的“工作”。cmt_fork() 返回 指向新任务的指针(为清楚起见,不进行错误检查)和 cmt_send() 将字符串作为消息发送到该任务。此时,消息只是存储 转换为任务数据。在第一次调用 cmt_pause() 时,每个实例都以循环方式获得控制权 时尚,第一件事就是收到发送给它的消息。然后 它们都进入无限循环,打印接收到的字符串,然后调用 cmt_sleep() - 一个睡眠函数,它连续调用 cmt_pause() 来表示给定数量的 秒。同时,主程序正忙着看键盘。

您可以从源代码中找出信号量、计时器和消息队列 和你自己的文档,我再举一个例子,这次来自 现实生活中的代码:

#include "cmtlib.h"
#include <dos.h>

static void interrupt far (*oldtick)(void);
static long watchdog,wdticks;

static void interrupt far newtick(void)
{
(*oldtick)();
watchdog++;
if (watchdog>wdticks) {
_asm cli
_asm pushf
_asm mov ax,0ffffh
_asm push ax
_asm xor ax,ax
_asm push ax
_asm iret
}
}

void startwatchdog(int sectimeout)
{
watchdog=0l;
wdticks=(long)sectimeout*18l+(long)(sectimeout/5);
if (!oldtick) {
oldtick=getvect(0x1c);
setvect(0x1c,newtick);
}
}

void stopwatchdog(void)
{
if (oldtick) {
setvect(0x1c,oldtick);
oldtick=NULL;
}
}

void clearwatchdog(void)
{
watchdog=0l;
}

/*--------------------------------*/
void idletask(void)
{
while (1) {
clearwatchdog();
sleep(1);
}
}

void main(void)
{
startwatchdog(60);
cmt_fork(idletask,512);
while (!kbit()) {
cmt_pause();
}
stopwatchdog();
getch();
}
当然,在现实生活中,您可能会有其他任务。此代码实现 一个可以检测代码是否已死的看门狗 - 前提是定时器中断 还活着。startwatchdog() 会将新的中断处理程序附加到用户计时器 处理程序,用于计算即时报价,并在达到预定义量时重新启动计算机。 idletask() 每秒清除一次计数器,从不允许计数器 只要多任务处理程序正常运行,就会溢出。Startwatchdog() 实现 以便可以多次调用 in 来设置新的超时值 - 我正在设置 它大约需要 10 分钟,如果我需要执行外部,有时甚至更长 我的代码中的程序。这个简单的看门狗在实践中效果很好,可以恢复 自动从大多数错误(包括麻烦的网络问题,共享 冲突和间歇性设备 I/O 错误)。

希望这段代码对你们所有人都有用。我很高兴收到任何 如果有的话,你会捐款,但你没有义务给我寄任何东西。 这段代码只是想免费:)。

版权所有 © Madis Kaal 2000-2024

posted @ 2024-06-07 23:11  firespeed  阅读(2)  评论(0编辑  收藏  举报