📄 thread.c
字号:
/* 包含头文件 */
#include <stdlib.h>
#include <setjmp.h>
#include <dos.h>
#include "stdefine.h"
#include "thread.h"
/* 常量定义 */
#define MAX_THREAD_NUM 16
#define THREAD_STACK_SIZE 512
#define THREAD_DEAD 0
#define THREAD_READY 1
#define THREAD_RUNNING 2
#define THREAD_STOPPED 3
#define _INT_1CH 0x1c
/* 类型定义 */
typedef struct
{
THREADPROC proc;
void *argv;
WORD status;
WORD timer;
WORD cycle;
jmp_buf jmpbuf;
BYTE stack[THREAD_STACK_SIZE];
} THREADITEM, PTHREADITEM;
/* 内部全局变量定义 */
static void interrupt (*old_int_1ch)(void);
static THREADITEM thread_list[MAX_THREAD_NUM] = {0};
static int cur_thread = 0;
/* 内部函数声明 */
static void interrupt MULTI_THREAD_MAN();
static void changetimer(WORD t);
/* 函数实现 */
BOOL InitMultiThread(WORD cycle)
{
memset(thread_list, 0, sizeof(THREADITEM) * MAX_THREAD_NUM);
cur_thread = 0;
/* main thread cycle */
thread_list[cur_thread].status = THREAD_RUNNING;
thread_list[cur_thread].timer = cycle;
thread_list[cur_thread].cycle = cycle;
old_int_1ch = getvect(_INT_1CH);
setvect(_INT_1CH, MULTI_THREAD_MAN);
return TRUE;
}
void CloseMultiThread()
{
changetimer(0); setvect(_INT_1CH, old_int_1ch);
}
int CreateThread(THREADPROC proc, void *argv, WORD cycle)
{
int i;
for (i=0; i<MAX_THREAD_NUM; i++)
{
if (thread_list[i].status == THREAD_DEAD)
{
thread_list[i].proc = proc;
thread_list[i].argv = argv;
thread_list[i].status = THREAD_READY;
thread_list[i].timer = cycle;
thread_list[i].cycle = cycle;
return i;
}
}
return NULL;
}
void DestroyThread(int id)
{
memset(&thread_list[id], 0, sizeof(THREADITEM));
}
void RunThread(int id)
{
disable();
thread_list[id].status = THREAD_RUNNING;
enable();
}
void StopThread(int id)
{
disable();
thread_list[id].status = THREAD_STOPPED;
enable();
}
/* 内部函数实现 */
static void changetimer(WORD t)
{
outportb(0x43, 0x3c);
outportb(0x40, LOWBYTE(t));
outportb(0x40, HIBYTE(t));
}
/* 线程调度函数,是整个系统的关键 */
static void interrupt MULTI_THREAD_MAN()
{
static int i;
static int temp;
/* 关中断 */
disable();
if (--thread_list[cur_thread].timer > 0)
{ /* 当前线程的时间片未用完,不进行线程调度 */
enable(); /* 开中断 */
return;
}
/* 当前线程的时间片用完,进行线程调度 */
thread_list[cur_thread].timer = thread_list[cur_thread].cycle; /* 重新分配时间片 */
if (!setjmp(thread_list[cur_thread].jmpbuf)) /* 保存当前线程的运行环境 */
{ /* 开始线程调度 */
for (i=0; i<MAX_THREAD_NUM; i++)
{ /* 查找下一个可调度的线程 */
cur_thread++;
cur_thread %= MAX_THREAD_NUM;
if (thread_list[cur_thread].status == THREAD_READY)
{
/* 为新线程分配堆栈 */
temp = (WORD)(thread_list[cur_thread].stack);
temp += THREAD_STACK_SIZE;
asm mov sp, temp;
asm mov ax, ds;
asm mov ss, ax;
/* 调用线程函数 */
thread_list[cur_thread].status = THREAD_RUNNING;
outp(0x20, 0x20); /* 清除中断屏蔽 */
enable(); /* 开中断 */
thread_list[cur_thread].proc(thread_list[cur_thread].argv);
/* 线程运行结束 */
disable(); /* 关中断 */
thread_list[cur_thread].status = THREAD_DEAD;
longjmp(thread_list[0].jmpbuf, 1); /* 返回主线程 */
break;
}
else if (thread_list[cur_thread].status == THREAD_RUNNING)
{ /* 调度线程 */
longjmp(thread_list[cur_thread].jmpbuf, 1);
break;
}
}
}
outp(0x20, 0x20); /* 清除中断屏蔽 */
enable(); /* 开中断 */
}
/* 以下是测试程序 */
int fun(void *n)
{
while (1)
{
sound(1000);
delay(20000);
nosound();
delay(20000);
}
}
int fun2(void *s)
{
printf("%s", s);
}
/* 演示了三个线程:主线程、fun 和 fun2 */
main()
{
int id;
int id2;
WORD i = 0;
changetimer(0xFFFF / 100);
InitMultiThread(1);
id = CreateThread(fun, NULL, 1);
id2 = CreateThread(fun2, (void*)"hello world !\r\n", 1);
for (i=0; i< 20; i++)delay(10000);
while (!kbhit())
{
printf("rockcarry %u\r\n", i++);
}
getch();
getch();
DestroyThread(id2);
DestroyThread(id);
CloseMultiThread();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -