嵌入式大厂面经 线程和进程常考面试题(持续更新中!)

这是一个嵌入式大厂面试题专栏,每天更新高频面试题。专栏将包含题目描述、详细解析、相关知识点扩展以及实际代码示例。内容涵盖操作系统、驱动开发、通信协议等核心领域,并结合实际项目经验进行分析。每道题目都会附带面试官可能的追问方向,帮助大家更好地准备面试!

进程和线程常考面试题总结

一、基本概念

1. 进程与线程的定义与区别

进程(Process)

  • 操作系统资源分配的基本单位
  • 拥有独立的内存空间和系统资源
  • 包含代码、数据、堆栈等

线程(Thread)

  • CPU调度的基本单位
  • 共享所属进程的内存空间和资源
  • 只拥有必要的运行资源(如程序计数器、寄存器和栈)

主要区别

资源占用

占用独立内存空间

共享进程内存空间

通信开销

较大(需IPC机制)

较小(直接访问共享数据)

创建开销

较大

较小

切换开销

较大(需保存/恢复更多上下文)

较小

安全性

较高(相互独立)

较低(共享内存可能导致冲突)

并发性

多进程并发

多线程并发

2. 进程状态及转换

五种基本状态

  • 创建(New):进程正在被创建
  • 就绪(Ready):进程等待被调度
  • 运行(Running):进程正在执行
  • 阻塞/等待(Blocked/Waiting):进程等待某事件发生
  • 终止(Terminated):进程执行完毕

状态转换图

  创建 -----> 就绪 <-----> 运行 -----> 终止
               ^           |
               |           v
               +------ 阻塞/等待

3. 线程状态及生命周期

线程状态(以Java为例):

  • 新建(New):线程对象已创建但未启动
  • 可运行(Runnable):线程已启动,等待CPU调度
  • 阻塞(Blocked):线程被锁阻塞,等待获取锁
  • 等待(Waiting):线程等待其他线程的通知
  • 计时等待(Timed Waiting):线程等待一段时间
  • 终止(Terminated):线程执行完毕

二、进程管理与通信

1. 进程调度算法

常见调度算法

先来先服务(FCFS)

按进程到达顺序执行

公平、简单

平均等待时间可能较长

批处理系统

短作业优先(SJF)

选择执行时间最短的进程

最小平均等待时间

可能导致饥饿,难以预测执行时间

批处理系统

优先级调度

按进程优先级执行

灵活性高

可能导致饥饿

实时系统

时间片轮转(RR)

每个进程分配固定时间片

响应时间短,公平

上下文切换开销大

分时系统

多级反馈队列

结合多种调度策略

兼顾交互性和吞吐量

实现复杂

通用操作系统

调度算法实现示例

// 时间片轮转调度算法简化实现
void RoundRobin(Process processes[], int n, int quantum) {
    int remaining_time[n];
    for (int i = 0; i < n; i++)
        remaining_time[i] = processes[i].burst_time;
    
    int t = 0; // 当前时间
    while (1) {
        bool done = true;
        
        // 遍历所有进程
        for (int i = 0; i < n; i++) {
            if (remaining_time[i] > 0) {
                done = false;
                
                // 执行时间片或剩余时间
                if (remaining_time[i] > quantum) {
                    t += quantum;
                    remaining_time[i] -= quantum;
                } else {
                    t += remaining_time[i];
                    processes[i].completion_time = t;
                    remaining_time[i] = 0;
                }
            }
        }
        
        // 所有进程都已完成
        if (done)
            break;
    }
}

2. 进程间通信(IPC)机制

常见IPC机制

管道(Pipe)

半双工通信通道

简单易用

只能用于有亲缘关系的进程,单向通信

父子进程通信

命名管道(FIFO)

具名的管道

可用于无亲缘关系进程

单向通信,容量有限

客户端-服务器通信

消息队列

存储消息的链表

异步通信,容量大

消息大小有限制

异步通信场景

共享内存

多进程共享的内存区域

速度最快

需要同步机制

大数据量高速通信

信号量

控制共享资源访问的计数器

实现简单

仅适用于简单同步

资源访问控制

套接字(Socket)

网络通信端点

可跨网络通信

开销较大

分布式系统通信

信号(Signal)

通知进程发生事件

异步处理

信息量有限

异常处理

共享内存实现示例

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>

#define SHM_SIZE 1024

int main() {
    key_t key = ftok("shmfile", 65);
    int shmid = shmget(key, SHM_SIZE, 0666|IPC_CREAT);
    
    // 附加到共享内存
    char *str = (char*)shmat(shmid, NULL, 0);
    
    printf("写入共享内存: ");
    fgets(str, SHM_SIZE, stdin);
    
    printf("共享内存数据: %s\n", str);
    
    // 从共享内存分离
    shmdt(str);
    
    // 删除共享内存
    shmctl(shmid, IPC_RMID, NULL);
    
    return 0;
}

3. 进程同步机制

常见同步问题

  • 生产者-消费者问题
  • 读者-写者问题
  • 哲学家就餐问题

同步机制

  • 互斥锁(Mutex):保证同一时间只有一个线程访问共享资源
  • 信号量(Semaphore):控制同时访问特定资源的线程数量
  • 条件变量(Condition Variable):线程等待特定条件满足
  • 屏障(Barrier):同步一组线程到达某一点

生产者-消费者问题实现

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SIZE 5

int buffer[BUFFER_SIZE];
int count = 0;
int in = 0, out = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;

void *producer(void *arg) {
    int item;
    while (1) {
        item = rand() % 100; // 生产一个随机数
        
        pthread_mutex_lock(&mutex);
        
        // 缓冲区满,等待
        while (count == BUFFER_SIZE) {
            pthread_cond_wait(¬_full, &mutex);
        }
        
        // 放入缓冲区
        buffer[in] = item;
        in = (in + 1) % BUFFER_SIZE;
        count++;
        
        printf("生产: %d\n", item);
        
        // 通知消费者
        pthread_cond_signal(¬_empty);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

void *consumer(void *arg) {
    int item;
    while (1) {
        pthread_mutex_lock(&mutex);
        
        // 缓冲区空,等待
        while (count == 0) {
            pthread_cond_wait(¬_empty, &mutex);
        }
        
        // 从缓冲区取出
        item = buffer[out];
        out = (out + 1) % BUFFER_SIZE;
        count--;
        
        printf("消费: %d\n", item);
        
        // 通知生产者
        pthread_cond_signal(¬_full);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

三、线程管理与同步

1. 线程创建与管理

线程创建方式(以POSIX线程为例):

#include <pthread.h>
#include <stdio.h>

void *thread_function(void *arg) {
    printf("线程ID: %ld\n", (long)pthread_self());
    return NULL;
}

int main() {
    pthread_t thread;
    int ret;
    
    // 创建线程
    ret = pthread_create(

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

嵌入式面试八股文全集 文章被收录于专栏

这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务