操作系统课程设计 基于DOS的多任务系统的实现

本文详细介绍了如何使用C语言在DOS环境下实现多任务系统,包括线程的创建与撤销,以及从先来先服务到时间片轮转的调度算法转换。通过调整时间片大小,观察调度效果。同时,利用记录型信号量解决线程间资源互斥访问及生产者消费者问题,最后探讨了消息缓冲通信的实现。所有代码在Turbo C环境中运行。
摘要由CSDN通过智能技术生成

内容要求:

(1)用C语言完成线程的创建和撤销,并按先来先服务方式对多个线程进行调度。

(2)将线程调度算法修改为时间轮转算法,实现时间片轮转调度。

(3)改变时间片的大小,观察结果的变化。

(4)假设两个线程共用一软件资源(如某一变量,或某一数据结构),请用记录型信号量来实现对它的互斥访问。

(5)假设有两个线程共享一个可存放5个整数的缓冲,其中一个线程不停地计算1至50的平方,并将结果放入缓冲,另一个线程不断地从缓冲中取出结果,并将它们打印出来,请用记录型信号量来实现这一生产者和消费者的同步问题。

(6)实现消息缓冲通信。


代码运行环境:Turbo C

#include <alloc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>

/* 状态码常量定义 */
#define FINISHED	0	/* 表示线程处于终止态或者TCB是空白状态 */
#define RUNNING	1	/* 表示线程处于运行态 */
#define READY	2	/* 表示线程处于就绪态 */
#define BLOCKED	3	/* 表示线程处于阻塞态 */

#define NTCB	10	/* NTCB是系统允许的最多任务数 */
#define NTEXT	20		/* 文本大小 */
#define NBUF	5		/* 缓冲区大小 */
#define NSTACK 1024		/* 私有栈大小 */

#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06

char far *indos_ptr = 0;	/* 该指针变量存放INDOS标志的地址 */
char far *crit_err_ptr = 0;	/* 该指针变量存放严重错误标志的地址 */

int timecount = 0;
int TL;					/* time slice时间片 */
int current = -1;		/* 当前进程的tcb下标 */
int n = 0;

typedef int (far *codeptr)(void);	/* 定义一个函数指针类型 */
void interrupt(*old_int8)(void);

/* 记录型信号量 */
typedef struct{
		int value;
		struct TCB *wq;
	}semaphore;

semaphore mutex = {1, NULL};	
semaphore mutexfb = {1, NULL};	/* 缓冲区互斥信号量 */
semaphore sfb = {NBUF, NULL};	/* 计算信号量 */
semaphore empty = {NBUF, NULL};
semaphore full = {0, NULL};

/* 消息缓冲区 */
struct buffer{
	int id;
	int size;
	char text[NTEXT];
	struct buffer *next;
}buf[NBUF], *freebuf;

struct TCB{
	unsigned char *stack;	/* 线程堆栈的起始位置 */
	unsigned ss;				/* 堆栈段址 */
	unsigned sp;				/* 堆栈指针 */
	char state;				/* 线程状态,取值可以是FINISHED, RUNNING, READY, BLOCKED */
	char name[NTEXT];		/* 线程的外部标识符 */
	struct buffer *mq;		/* 接收线程的消息队列首指针 */
	semaphore mutex;			/* 接收线程的消息队列的互斥信号量 */
	semaphore sm;			/* 接收线程的消息队列的计数信号量,用于实现同步 */
	struct TCB *next;
} tcb[NTCB];

struct int_regs{
	unsigned bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags, off, seg;
};

int intbuf[NBUF], buftemp;
int in = 0, out = 0;

void over();
void destroy(int id);
void wait(semaphore *sem);
void signal(semaphore *sem);
void block(struct TCB **qp);
void wakeupFirst(struct TCB **qp);
void send(char *receiver, char *a, int size);
int receive(char *sender, char *b);

/* InitDos()函数:功能是获得INDOS标志地址和严重错误标志的地址 */
void InitDos(void)
{
	union REGS regs;
	struct SREGS segregs;
	
	/* 获得INDOS标志的地址 */
	regs.h.ah = GET_INDOS;
	/* intdosx(): Turbo C的库函数,其功能是调用DOS的INT21H中断 */
	intdosx(®s, ®s, &segregs);
	/* MK_FP(): 不是一个函数,只是一个宏 */
	/* 其功能是做段基址加上偏移地址的运算,也就是取实际地址。 */
	indos_ptr = MK_FP(segregs.e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值