设备分配核心数据结构全解析

设备分配用数据结构详解

一、设备管理概述

1.1 设备分类

设备类型 特点 例子
独占设备 一段时间内只允许一个进程使用 打印机、磁带机
共享设备 多个进程可同时使用 磁盘、网卡
虚拟设备 通过虚拟化技术模拟的设备 SPOOLing系统中的虚拟打印机

1.2 设备分配目标

  1. 提高设备利用率:避免设备空闲
  2. 保证公平性:避免进程饥饿
  3. 避免死锁:合理分配资源
  4. 与设备无关性:用户无需了解设备细节

二、核心数据结构

2.1 系统设备表(SDT - System Device Table)

作用:记录系统中所有设备的基本信息

c 复制代码
struct SystemDeviceTable {
    int device_count;                   // 系统设备总数
    DeviceControlTable* devices[MAX_DEVICES];  // 指向各设备的DCT指针
    int free_device_count;              // 空闲设备数
    // 其他系统级信息...
};

内存中的存储形式

复制代码
SDT:
┌─────────────────────┐
│ device_count = 5    │
├─────────────────────┤
│ devices[0] → DCT1   │
│ devices[1] → DCT2   │
│ devices[2] → DCT3   │
│ devices[3] → DCT4   │
│ devices[4] → DCT5   │
├─────────────────────┤
│ free_device_count=3 │
└─────────────────────┘

2.2 设备控制表(DCT - Device Control Table)

作用:每个设备一张,记录设备状态和控制信息

c 复制代码
struct DeviceControlTable {
    // 设备标识信息
    char device_id[20];                 // 设备标识符
    DeviceType type;                    // 设备类型(字符/块/网络)
    DeviceStatus status;                // 设备状态(空闲/忙碌/故障)
    
    // 设备连接信息
    int controller_id;                  // 连接的控制器ID
    ControllerControlTable* controller; // 指向COCT的指针
    int channel_id;                     // 连接的通道ID
    ChannelControlTable* channel;       // 指向CHCT的指针
    
    // 设备分配信息
    int attached_process;               // 当前使用进程ID(-1表示空闲)
    Queue* wait_queue;                  // 等待该设备的进程队列
    
    // 设备特性
    int transfer_rate;                  // 数据传输速率(KB/s)
    int block_size;                     // 块大小(字节)
    bool shareable;                     // 是否可共享
    
    // 状态信息
    time_t last_used;                   // 最后使用时间
    int error_count;                    // 错误计数
    // ... 其他设备特定信息
};

DCT示例(打印机)

复制代码
打印机DCT:
┌─────────────────────┐
│ device_id: "PRN001" │
│ type: CHARACTER     │
│ status: BUSY        │
├─────────────────────┤
│ controller_id: 3    │
│ channel_id: 1       │
├─────────────────────┤
│ attached_process: 15│
│ wait_queue: [P18,P22]│
├─────────────────────┤
│ transfer_rate: 100  │
│ shareable: FALSE    │
└─────────────────────┘

2.3 控制器控制表(COCT - Controller Control Table)

作用:每个控制器一张,管理设备控制器

c 复制代码
struct ControllerControlTable {
    char controller_id[20];             // 控制器标识符
    ControllerStatus status;            // 控制器状态
    DeviceType supported_types;         // 支持的设备类型
    
    // 连接信息
    int channel_id;                     // 连接的通道ID
    ChannelControlTable* channel;       // 指向CHCT
    
    // 设备连接
    int connected_devices[MAX_PER_CONTROLLER];  // 连接的设备ID数组
    int device_count;                   // 连接设备数
    
    // 分配信息
    int attached_process;               // 当前使用进程ID
    Queue* wait_queue;                  // 等待控制器的进程队列
    
    // 控制器特性
    int buffer_size;                    // 缓冲区大小
    bool dma_enabled;                   // 是否支持DMA
    // ... 其他控制器特定信息
};

2.4 通道控制表(CHCT - Channel Control Table)

作用:每个通道一张,管理I/O通道

c 复制代码
struct ChannelControlTable {
    char channel_id[20];                // 通道标识符
    ChannelType type;                   // 通道类型(字节多路/数组选择/DMA)
    ChannelStatus status;               // 通道状态
    
    // 连接信息
    int connected_controllers[MAX_PER_CHANNEL];  // 连接的控制器ID
    int controller_count;               // 连接控制器数
    
    // 分配信息
    int attached_process;               // 当前使用进程ID
    Queue* wait_queue;                  // 等待通道的进程队列
    
    // 通道特性
    int bandwidth;                      // 带宽(MB/s)
    bool interrupt_enabled;             // 是否支持中断
    // ... 其他通道特定信息
};

2.5 设备分配请求表(DART)

作用:记录进程的设备分配请求

c 复制代码
struct DeviceAllocationRequest {
    int request_id;                     // 请求ID
    int process_id;                     // 请求进程ID
    char device_id[20];                 // 请求的设备ID
    int controller_id;                  // 请求的控制器ID
    int channel_id;                     // 请求的通道ID
    
    // 请求参数
    int operation_type;                 // 操作类型(读/写/控制)
    int priority;                       // 请求优先级
    time_t request_time;                // 请求时间
    
    // 状态信息
    RequestStatus status;               // 请求状态(等待/分配/完成)
    int allocated_device;               // 分配的设备ID(-1表示未分配)
    time_t allocation_time;             // 分配时间
    
    // 链接信息(用于队列)
    DeviceAllocationRequest* next;      // 下一请求
    DeviceAllocationRequest* prev;      // 上一请求
};

三、数据结构关系图

3.1 整体关系

复制代码
进程PCB
    ↓ (包含设备分配信息)
系统设备表(SDT)
    ↓ (指向各个设备)
设备控制表(DCT) → 控制器控制表(COCT) → 通道控制表(CHCT)
    ↓                    ↓                    ↓
设备队列           控制器队列           通道队列

3.2 数据结构链接示例

c 复制代码
// 简化的数据结构链接
struct ProcessControlBlock {
    int pid;
    // ... 其他进程信息
    DeviceAllocation* device_allocations;  // 进程已分配的设备列表
};

struct DeviceAllocation {
    DCT* device;            // 分配的设备
    COCT* controller;       // 分配的控制器
    CHCT* channel;          // 分配的通道
    time_t allocation_time;
    DeviceAllocation* next; // 下一个分配
};

四、设备分配算法数据结构

4.1 先来先服务(FCFS)分配

c 复制代码
// FCFS等待队列
struct FCFSQueue {
    DeviceAllocationRequest* front;  // 队首
    DeviceAllocationRequest* rear;   // 队尾
    int count;                      // 等待数量
    
    // 操作方法
    void enqueue(DeviceAllocationRequest* request);
    DeviceAllocationRequest* dequeue();
    DeviceAllocationRequest* peek();
};

4.2 优先级分配

c 复制代码
// 优先队列(最小堆实现)
struct PriorityQueue {
    DeviceAllocationRequest* heap[MAX_REQUESTS];
    int size;
    
    // 堆操作方法
    void heapify_up(int index);
    void heapify_down(int index);
    void insert(DeviceAllocationRequest* request);
    DeviceAllocationRequest* extract_min();
};

4.3 银行家算法(避免死锁)

c 复制代码
// 资源分配图
struct ResourceAllocationGraph {
    int process_count;      // 进程数
    int resource_count;     // 资源数(设备数)
    
    // 矩阵表示
    int allocation[MAX_PROCESSES][MAX_RESOURCES];  // 已分配矩阵
    int request[MAX_PROCESSES][MAX_RESOURCES];     // 请求矩阵
    int available[MAX_RESOURCES];                  // 可用资源向量
    int max[MAX_PROCESSES][MAX_RESOURCES];         // 最大需求矩阵
    
    // 安全状态检测
    bool is_safe_state();
    
    // 资源分配
    bool allocate_resources(int process_id, int resource_id, int units);
    
    // 资源回收
    void release_resources(int process_id, int resource_id, int units);
};

五、SPOOLing系统数据结构

5.1 输入井和输出井

c 复制代码
// 输出井(用于打印机等输出设备)
struct OutputWell {
    char well_id[20];               // 井标识符
    int total_size;                 // 总容量
    int used_size;                  // 已用容量
    int block_size;                 // 块大小
    
    // 文件队列
    struct {
        char filename[50];          // 假脱机文件名
        int process_id;             // 所属进程
        int file_size;              // 文件大小
        int priority;               // 打印优先级
        time_t arrival_time;        // 到达时间
    } files[MAX_SPOOL_FILES];
    
    int file_count;                 // 文件数量
};

5.2 SPOOLing调度表

c 复制代码
struct SpoolingScheduleTable {
    // 输入井调度
    struct {
        char device_id[20];         // 输入设备ID
        OutputWell* input_well;     // 对应的输入井
        ProcessQueue* reader_queue; // 读取进程队列
    } input_schedule[MAX_INPUT_DEVICES];
    
    // 输出井调度
    struct {
        char device_id[20];         // 输出设备ID
        OutputWell* output_well;    // 对应的输出井
        ProcessQueue* writer_queue; // 写入进程队列
        int current_file_index;     // 当前打印文件索引
    } output_schedule[MAX_OUTPUT_DEVICES];
    
    // 调度算法
    SchedulingAlgorithm algorithm;  // 调度算法(FCFS/优先级)
};

六、现代操作系统中的设备管理数据结构

6.1 Linux设备管理(简化版)

c 复制代码
// Linux设备结构(简化的字符设备)
struct CharDevice {
    // 设备标识
    dev_t dev;                      // 设备号(主设备号+次设备号)
    char name[64];                  // 设备名称
    
    // 操作函数指针
    struct file_operations* fops;   // 文件操作函数集
    
    // 设备状态
    atomic_t open_count;            // 打开计数
    struct mutex lock;              // 互斥锁
    wait_queue_head_t wait_queue;   // 等待队列
    
    // 设备私有数据
    void* private_data;
    
    // 设备列表管理
    struct list_head list;          // 链表节点
};

// 设备类别
struct DeviceClass {
    char name[64];                  // 类别名称
    struct list_head devices;       // 设备链表头
    int device_count;               // 设备数量
    struct kobject* kobj;           // 内核对象
};

6.2 Windows设备管理

c 复制代码
// Windows设备对象(简化的WDM模型)
typedef struct _DEVICE_OBJECT {
    // 设备对象头
    SHORT Type;                     // 对象类型
    SHORT Size;                     // 对象大小
    
    // 设备信息
    struct _DRIVER_OBJECT* DriverObject;  // 驱动对象
    struct _DEVICE_OBJECT* NextDevice;    // 下一个设备
    struct _DEVICE_OBJECT* AttachedDevice; // 附加设备
    
    // 设备特性
    ULONG DeviceType;               // 设备类型
    ULONG Characteristics;          // 设备特性
    ULONG Flags;                    // 设备标志
    
    // I/O管理
    struct _VPB* Vpb;               // 卷参数块
    PVOID DeviceExtension;          // 设备扩展
    // ... 其他Windows特定字段
} DEVICE_OBJECT;

七、设备分配算法实现示例

7.1 设备分配函数

c 复制代码
// 设备分配主函数
int allocate_device(int process_id, 
                   DeviceRequest* request, 
                   SystemDeviceTable* sdt) {
    
    // 1. 查找合适设备
    DCT* device = find_suitable_device(request, sdt);
    if (!device) {
        add_to_wait_queue(process_id, request);
        return WAIT_FOR_DEVICE;
    }
    
    // 2. 分配控制器
    COCT* controller = allocate_controller(device->controller);
    if (!controller) {
        return CONTROLLER_BUSY;
    }
    
    // 3. 分配通道
    CHCT* channel = allocate_channel(controller->channel);
    if (!channel) {
        release_controller(controller);
        return CHANNEL_BUSY;
    }
    
    // 4. 更新数据结构
    device->status = BUSY;
    device->attached_process = process_id;
    
    controller->status = BUSY;
    controller->attached_process = process_id;
    
    channel->status = BUSY;
    channel->attached_process = process_id;
    
    // 5. 记录分配信息
    DeviceAllocation* allocation = create_allocation_record(
        process_id, device, controller, channel);
    
    add_to_process_allocation_list(process_id, allocation);
    
    return ALLOCATION_SUCCESS;
}

7.2 设备回收函数

c 复制代码
void release_device(int process_id, int device_id) {
    // 1. 查找分配记录
    DeviceAllocation* allocation = 
        find_allocation(process_id, device_id);
    
    if (!allocation) {
        return;  // 未找到分配记录
    }
    
    // 2. 释放设备
    DCT* device = allocation->device;
    device->status = IDLE;
    device->attached_process = -1;
    
    // 3. 释放控制器(如果无其他设备使用)
    if (controller_idle(allocation->controller)) {
        allocation->controller->status = IDLE;
        allocation->controller->attached_process = -1;
    }
    
    // 4. 释放通道(如果无其他控制器使用)
    if (channel_idle(allocation->channel)) {
        allocation->channel->status = IDLE;
        allocation->channel->attached_process = -1;
    }
    
    // 5. 检查等待队列,唤醒等待进程
    if (!is_empty(device->wait_queue)) {
        Process* next_process = dequeue(device->wait_queue);
        wakeup_process(next_process);
    }
    
    // 6. 删除分配记录
    remove_allocation_record(process_id, allocation);
    free(allocation);
}

八、数据结构优化技巧

8.1 哈希表加速查找

c 复制代码
// 设备ID到DCT的哈希映射
struct DeviceHashTable {
    struct HashEntry {
        char device_id[20];
        DCT* device;
        struct HashEntry* next;
    } *table[HASH_SIZE];
    
    // 哈希函数
    int hash_function(char* device_id) {
        int hash = 0;
        for (int i = 0; device_id[i]; i++) {
            hash = (hash * 31 + device_id[i]) % HASH_SIZE;
        }
        return hash;
    }
    
    // 查找设备
    DCT* find_device(char* device_id) {
        int index = hash_function(device_id);
        HashEntry* entry = table[index];
        while (entry) {
            if (strcmp(entry->device_id, device_id) == 0) {
                return entry->device;
            }
            entry = entry->next;
        }
        return NULL;
    }
};

8.2 位图管理空闲设备

c 复制代码
// 使用位图高效管理设备状态
struct DeviceBitmap {
    unsigned int* bits;      // 位数组
    int total_devices;       // 设备总数
    int free_count;          // 空闲设备数
    
    // 分配设备
    int allocate() {
        for (int i = 0; i < (total_devices + 31)/32; i++) {
            if (bits[i] != 0xFFFFFFFF) {  // 非全1
                // 查找第一个0位
                int bit = ffs(~bits[i]) - 1;  // ffs返回最低位的1的位置
                int device_id = i * 32 + bit;
                bits[i] |= (1 << bit);    // 设置为1(忙碌)
                free_count--;
                return device_id;
            }
        }
        return -1;  // 无空闲设备
    }
    
    // 释放设备
    void release(int device_id) {
        int word = device_id / 32;
        int bit = device_id % 32;
        bits[word] &= ~(1 << bit);  // 设置为0(空闲)
        free_count++;
    }
};

九、总结要点

9.1 核心数据结构记忆表

数据结构 缩写 作用 关键字段
系统设备表 SDT 管理所有设备 devices[], free_count
设备控制表 DCT 单个设备信息 status, controller, wait_queue
控制器表 COCT 控制器管理 status, channel, connected_devices
通道控制表 CHCT 通道管理 status, bandwidth, wait_queue
设备分配表 DART 记录分配请求 process_id, device_id, status

9.2 设备分配流程

  1. 进程请求 → 2. 查找SDT → 3. 检查DCT → 4. 分配COCT → 5. 分配CHCT → 6. 更新状态 → 7. 返回结果

9.3 设计原则

  1. 层次化:设备→控制器→通道的层次管理
  2. 状态记录:准确记录每个资源的状态
  3. 队列管理:合理处理等待进程
  4. 死锁避免:使用银行家算法等避免死锁
  5. 效率优化:使用哈希表、位图等提高效率

这些数据结构共同构成了操作系统中设备管理的核心框架,确保了设备资源的有效分配和管理。

相关推荐
机器视觉知识推荐、就业指导2 小时前
Qt 小技巧:如何用 Q_PROPERTY 管理属性
服务器·数据库·qt
星辰&与海2 小时前
操作系统引导过程
服务器
比奇堡派星星2 小时前
Linux OOM Killer
linux·开发语言·arm开发·驱动开发
张心独酌2 小时前
Rust开发案例库-静态服务器
服务器·开发语言·rust
起个名字费劲死了2 小时前
QT + Socket 客户端/服务端 公网通讯
服务器·c++·qt·socket
wifi chicken3 小时前
Linux 内核开发之单链表的增删查改详解
linux·数据结构·链表
jiuri_12153 小时前
深入理解 Linux 内核同步机制
linux·内核
HarmonLTS3 小时前
Python Socket网络通信详解
服务器·python·网络安全
sun0077003 小时前
androd和qnx判断实网卡还是虚网卡
运维·服务器·网络