嵌入式操作系统面试高频考点解析

嵌入式操作系统面试高频考点解析

1. 进程与线程

1.1 基本概念差异

  • 进程:操作系统资源分配的最小单位,拥有独立的地址空间
  • 线程:CPU调度的基本单位,共享进程地址空间但拥有独立堆栈和局部变量

1.2 关键特性对比

特性进程线程
地址空间独立共享
健壮性一个进程崩溃不影响其他线程崩溃可能影响同进程其他线程
创建开销较大较小
上下文切换开销较大较小

2. 进程间通信机制

2.1 管道通信

// 无名管道创建示例 int pipe(int pipefd[2]);
  • 无名管道:仅限亲缘关系进程间通信,单向字节流
  • 有名管道(FIFO):突破亲缘限制,通过文件系统路径访问

2.2 其他通信方式

  1. 消息队列:数据块传输,需用户/内核空间拷贝
  2. 共享内存:最高效但需处理资源竞争
  3. 信号:异步事件通知机制
  4. 信号量:同步互斥控制
  5. Socket:跨主机通信解决方案

3. 进程调度算法

3.1 基础算法

  • FCFS:先到先服务,简单但平均等待时间长
  • SJF:最短作业优先,理论上最优但需预知运行时间
  • 优先级调度:可能产生饥饿现象

3.2 高级算法

  • 时间片轮转:公平但上下文切换开销大
  • 多级反馈队列
    • 多级队列,优先级递减
    • 时间片递增
    • 新进程进入最高优先级队列

4. 特殊进程类型

4.1 孤儿进程

  • 产生条件:父进程先于子进程终止
  • 处理机制:被init进程(pid=1)收养
  • 资源回收:由init进程负责wait

5. 线程同步机制

5.1 同步原语对比

机制适用场景特点
互斥量临界区保护简单高效
读写锁读多写少允许并发读
条件变量事件等待需与互斥量配合使用
信号量资源计数可跨进程
自旋锁短临界区忙等待不释放CPU

6. 进程内存布局

6.1 Linux进程地址空间

  1. 内核空间:运行操作系统核心代码
  2. 栈区:自动管理,存放局部变量和函数调用信息
  3. 堆区:动态内存分配区域
  4. 数据段
    • .bss:未初始化全局变量
    • .data:已初始化全局变量
  5. 代码段:只读的程序指令

7. 内存管理问题

7.1 内存碎片类型

  • 外部碎片:空闲内存总量足够但无法满足连续分配
  • 内部碎片:分配单元未使用部分

7.2 解决方案

  • 内存池技术
  • slab分配器
  • 紧凑(compaction)技术

8. 堆栈对比分析

8.1 核心差异

特性
管理方式编译器自动分配释放程序员手动控制
分配效率高(指针移动即可)低(需查找合适内存块)
容量限制较小(通常MB级)较大(受虚拟内存限制)
碎片问题存在外部和内部碎片

9. 同步原语深入

9.1 互斥锁vs信号量

  • 互斥锁:二元状态,严格互斥访问
  • 信号量:计数机制,可实现复杂同步模式

9.2 使用注意事项

  • 避免锁嵌套导致的死锁
  • 注意锁粒度对性能的影响
  • 优先使用读写锁优化读多写少场景

10. 同步与异步

10.1 执行流程差异

// 同步调用示例 result = sync_call(); // 异步调用示例 async_call(callback);

10.2 适用场景

  • 同步:流程严格依赖调用结果
  • 异步:提高系统吞吐量,避免阻塞

11. 死锁问题

11.1 必要条件

  1. 互斥访问
  2. 占有并等待
  3. 不可抢占
  4. 循环等待

11.2 解决方案

  • 预防:破坏任一必要条件
    • 资源预分配
    • 允许资源抢占
    • 强制资源有序申请
  • 检测与恢复:定期检测死锁并采取措施

11.3 实际工程建议

  • 统一锁获取顺序
  • 使用超时机制
  • 避免长时间持有锁