嵌入式大厂面经 Linux进程管理常见面试题(持续更新中!)
这是一个嵌入式大厂面试题专栏,每天更新高频面试题。专栏将包含题目描述、详细解析、相关知识点扩展以及实际代码示例。内容涵盖操作系统、驱动开发、通信协议等核心领域,并结合实际项目经验进行分析。每道题目都会附带面试官可能的追问方向,帮助大家更好地准备面试!
Linux进程调度和进程创建相关面试题
一、Linux进程调度基础
1. 进程调度的概念
Linux进程调度是操作系统核心功能之一,负责决定哪个进程在CPU上运行,以及运行多长时间。调度器的目标是在保证公平性的同时,最大化系统吞吐量和最小化响应时间。
2. Linux调度器的发展
- O(1)调度器:Linux 2.6早期版本使用,常数时间复杂度
- CFS(完全公平调度器):从Linux 2.6.23开始引入,现在的主流调度器
- 实时调度器:用于实时任务,包括SCHED_FIFO和SCHED_RR策略
- BFS(脑残调度器)和MuQSS:第三方调度器,针对桌面响应优化
3. CFS调度器原理
CFS基于"虚拟运行时间"概念,追踪每个进程的运行时间:
- 使用红黑树数据结构组织进程
- 进程的虚拟运行时间越小,获得CPU的优先级越高
- 进程运行时,其虚拟运行时间增加
- 目标是让所有进程的虚拟运行时间接近
4. 调度策略和优先级
Linux支持多种调度策略:
- SCHED_OTHER(CFS):普通进程的默认策略
- SCHED_BATCH:批处理进程,不需要交互
- SCHED_IDLE:优先级最低的进程
- SCHED_FIFO:实时进程,先进先出,不会被抢占(除非被更高优先级进程)
- SCHED_RR:实时进程,时间片轮转
优先级系统:
- nice值:范围-20到19,值越小优先级越高,默认为0
- 实时优先级:范围1-99,值越大优先级越高
二、进程创建相关系统调用
1. fork系统调用
fork()
是Unix/Linux中创建进程的传统方法:
#include <unistd.h> pid_t fork(void);
特点:
- 创建调用进程的副本(子进程)
- 子进程获得父进程数据空间、堆、栈的副本
- 父子进程共享代码段(只读)
- 采用写时复制(Copy-On-Write)技术优化内存使用
- 返回值:父进程中返回子进程PID,子进程中返回0,失败返回-1
示例:
#include <stdio.h> #include <unistd.h> int main() { pid_t pid = fork(); if (pid < 0) { // 创建失败 perror("fork failed"); return 1; } else if (pid == 0) { // 子进程 printf("子进程,PID: %d,父进程PID: %d\n", getpid(), getppid()); } else { // 父进程 printf("父进程,PID: %d,子进程PID: %d\n", getpid(), pid); } return 0; }
2. vfork系统调用
vfork()
是fork()
的一种特殊形式:
#include <unistd.h> pid_t vfork(void);
特点:
- 创建进程的目的是执行exec系列函数
- 子进程与父进程共享地址空间(不使用写时复制)
- 父进程会被挂起,直到子进程调用exec或exit
- 子进程必须小心不修改共享的变量
- 现代系统中,fork的性能已经很好,vfork使用较少
示例:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { pid_t pid = vfork(); if (pid < 0) { // 创建失败 perror("vfork failed"); return 1; } else if (pid == 0) { // 子进程 printf("子进程,PID: %d\n", getpid()); // 子进程必须调用exec或exit _exit(0); // 注意使用_exit而非exit } else { // 父进程 printf("父进程,PID: %d,子进程PID: %d\n", getpid(), pid); } return 0; }
3. clone系统调用
clone()
是Linux特有的系统调用,提供更细粒度的控制:
#define _GNU_SOURCE #include <sched.h> int clone(int (*fn)(void *), void *stack, int flags, void *arg, ...);
特点:
- 允许选择父子进程间共享的资源(如文件描述符、信号处理等)
- 是实现线程的基础(pthread库在底层使用clone)
- 通过flags参数控制共享程度
- 常用flags: CLONE_FILES:共享文件描述符表CLONE_FS:共享文件系统信息CLONE_VM:共享内存空间CLONE_SIGHAND:共享信号处理函数
示例:
#define _GNU_SOURCE #include <stdio.h> #include <sched.h> #include <stdlib.h> #include <unistd.h> #define STACK_SIZE (1024 * 1024) // 1MB栈空间 // 子进程执行的函数 int child_func(void *arg) { printf("子进程,P
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。