協作多工庫

firespeed發表於2024-06-07

協作多工庫

描述

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

相關文章