模拟Windows线程切换(ThreadSwitch)
正在运行的线程在KPCR里,等待的线程在等待链表中,调度中的线程在那32个调度链表中。
创建它是从下标1的位置开始存的而不是0,因为main需要一个线程。
创建的线程还不能调度还需要初始化的环境,寄存器的值、当前线程的堆栈要确定
模拟线程切换总结:
- 线程不是被动切换的,而是主动让出CPU
- 线程切换并没有使用TSS来保存寄存器,而是使用堆栈.
- 线程切换的过程就是堆栈切换的过程
以下是代码:
ThreadSwitch.h
#pragma once
#include <windows.h>
#include "stdio.h"
//最大支持的线程数
#define MAXGMTHREAD 100
//线程信息的结构
typedef struct
{
char* name; //线程名 相当于线程ID
int Flags; //线程状态
int SleepMillsecondDot; //休眠时间
void* initialStack; //线程堆栈起始位置
void* StackLimit; //线程堆栈界限
void* KernelStack; //线程堆栈当前位置,也就是ESP
void* lpParameter; //线程函数的参数
void(*func)(void* lpParameter); //线程函数
}GMThread_t;
void GMSleep(int MilliSeconds);
int RegisterGMThread(char* name, void(*func)(void*lpParameter), void* lpParameter);
void Scheduling();
ThreadSwitch.c
#include "ThreadSwitch.h"
//定义线程栈的大小
#define GMTHREADSTACKSIZE 0x80000
//当前线程的索引
int CurrentThreadIndex = 0;
//线程的列表
GMThread_t GMThreadList[MAXGMTHREAD] = {
NULL, 0 };
//线程状态的标志
enum FLAGS
{
GMTHREAD_CREATE = 0x1,
GMTHREAD_READY = 0x2,
GMTHREAD_SLEEP = 0x4,
GMTHREAD_EXIT = 0x8,
};
//启动线程的函数
void GMThreadStartup(GMThread_t* GMThreadp)
{
GMThreadp->func(GMThreadp->lpParameter);
GMThreadp->Flags = GMTHREAD_EXIT;
Scheduling();
return;
}
//空闲线程的函数