对I/O设备的控制方式与假脱机SPOOLing

对I/O设备的控制方式

1.使用轮询的可编程I/O形式

  启动输入数据时,将状态寄存器置为1,然后不断检测该标志,直到标志寄存器变为0,证明输入数据结束。

2.使用中断的可编程I/O形式

  当进程请求I/O时,立刻中断CPU,保存现场后,交给相应的中断处理程序。有I/O就中断。而在I/O时,CPU可以和I/O设备并行执行。

3.DMA直接存储器访问

  四类寄存器:指令寄存器、地址寄存器、数据寄存器和数据计数器。读磁盘时,命令送至指令寄存器,数据地址至地址寄存器,待读入的字节数存入数据计数器,磁盘的源地址也要送至DMA控制器的I/O逻辑上。然后启动DMA。

4.I/O通道

  硬件概念,将简单的I/O指令由CPU指定交给I/O通道。其本质是一个专门执行I/O命令的简易 “CPU” ,CPU收到I/O请求时,将其转给I/O通道,之后直到执行完,CPU都不再管,最后I/O通道向CPU报告完成。

假脱机SPOOLing

  在多道程序技术中,可以用一道进程模拟外围I/O设备机器,将I/O输入数据转到高速磁盘;另一道进程负责从磁盘到I/O输出设备转移数据。

1.SPOOLing组成

(1)输入井和输出井

  磁盘开辟的两块区域,输入井模拟输入,用于收集数据;输出井模拟输出,用于提取数据。文件的形式管理数据。

(2)输入缓冲区和输出缓冲区

  内存中开辟的两块缓冲区,用于协调CPU与磁盘的速度不一致。

(3)输入输出进程

  负责从I/O设备得到数据放入输入井的输入进城;负责将数据从输出井传递到I/O输出设备的输出进程。

(4)井管理程序

  用于控制进程与磁盘井的数据交互。所有的入井出井操作都由井管理程序执行。

2.SPOOLing系统的特点

(1)提高了I/O速度:有专门的I/O进程,缓解了CPU与I/O设备的速度问题

(2)将独占设备改为共享设备:并没有为进程分配真实的物理设备,而是为进程分配一个空盘快和一个请求表

(3)实现了虚拟设备功能:所有进程会认为自己独占设备,但实际共享。

3.假脱机打印机系统

(1)磁盘缓冲区:暂存用户数据

(2)打印缓冲区:缓和CPU和磁盘设备的速度问题

(3)假脱机管理进程和假脱机打印进程:管理进程负责为每个要求打印的用户生成一个数据文件,并放入队列中;由打印进程扫描队列打印

 

转载于:https://www.cnblogs.com/fusiji/p/11409771.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 I/O 设备管理 spooling 技术例程库的 C 代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #define MAX_QUEUE_SIZE 10 #define MAX_LINE_LENGTH 1024 typedef struct { char *line; int length; } Line; typedef struct { Line queue[MAX_QUEUE_SIZE]; int front; int rear; int size; pthread_mutex_t mutex; pthread_cond_t cond_full; pthread_cond_t cond_empty; } Spooler; void init_spooler(Spooler *spooler) { spooler->front = 0; spooler->rear = 0; spooler->size = 0; pthread_mutex_init(&spooler->mutex, NULL); pthread_cond_init(&spooler->cond_full, NULL); pthread_cond_init(&spooler->cond_empty, NULL); } void destroy_spooler(Spooler *spooler) { pthread_mutex_destroy(&spooler->mutex); pthread_cond_destroy(&spooler->cond_full); pthread_cond_destroy(&spooler->cond_empty); } void enqueue(Spooler *spooler, const char *line) { pthread_mutex_lock(&spooler->mutex); while (spooler->size == MAX_QUEUE_SIZE) { pthread_cond_wait(&spooler->cond_full, &spooler->mutex); } spooler->queue[spooler->rear].length = strlen(line); spooler->queue[spooler->rear].line = malloc(spooler->queue[spooler->rear].length + 1); strcpy(spooler->queue[spooler->rear].line, line); spooler->rear = (spooler->rear + 1) % MAX_QUEUE_SIZE; spooler->size++; pthread_cond_signal(&spooler->cond_empty); pthread_mutex_unlock(&spooler->mutex); } Line dequeue(Spooler *spooler) { pthread_mutex_lock(&spooler->mutex); while (spooler->size == 0) { pthread_cond_wait(&spooler->cond_empty, &spooler->mutex); } Line line = spooler->queue[spooler->front]; spooler->front = (spooler->front + 1) % MAX_QUEUE_SIZE; spooler->size--; pthread_cond_signal(&spooler->cond_full); pthread_mutex_unlock(&spooler->mutex); return line; } void *spooler_thread(void *arg) { Spooler *spooler = (Spooler *) arg; while (1) { Line line = dequeue(spooler); printf("Printing: %s\n", line.line); free(line.line); } } void print(const char *line, Spooler *spooler) { enqueue(spooler, line); } int main() { Spooler spooler; init_spooler(&spooler); pthread_t thread; pthread_create(&thread, NULL, spooler_thread, &spooler); char line[MAX_LINE_LENGTH]; while (fgets(line, MAX_LINE_LENGTH, stdin)) { print(line, &spooler); } destroy_spooler(&spooler); pthread_join(thread, NULL); return 0; } ``` 这段代码定义了一个 Spooler 结构体,其中包含一个循环队列,一个互斥锁和两个条件变量。enqueue 函数将一行字符插入到队列中,dequeue 函数从队列中取出一行字符。spooler_thread 函数是一个长期运行的线程,它不断从队列中取出字符并打印。 在 main 函数中,我们首先初始化一个 Spooler 实例,然后创建一个线程来处理队列中的字符。接下来,我们从标准输入读取字符,并将其插入到队列中。最后,我们销毁 Spooler 实例并等待线程结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值