【秋招】嵌入式面试八股文 - 操作系统 篇

本文为 第六章操作系统 部分,具体整篇目录可以看前言!

【秋招】嵌入式面试八股文分享

第一部分(纯八股)

6. 操作系统

6.1 什么是进程?什么是线程?

       进程是资源分配的基本单位,它是程序执行时的一个实例,在程序运行时创建。

       线程是程序执行的最小单位,是进程的一个执行流,一个进程由多个线程组成的。

       协程是一种比线程更加轻量级的存在。一个线程也可以拥有多个协程。其执行过程更类似于子例程,或者说不带返回值的函数调用。

6.2 内核线程和用户线程的区别?

1. 内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。

2. 用户级线程的创建、撤消和调度不需要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的创建、撤消和调度都需OS内核提供支持,而且与进程的创建、撤消和调度大体是相同的。

3. 用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。

4. 在只有用户级线程的系统内,CPU调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。

5. 用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。

6.3 进程和线程有什么区别?

1、根本区别

       进程是资源分配的基本单位,线程是程序执行的最小单位

2、资源开销

       进程有自己独立地址空间(代码空间和数据空间),每启动一个进程,系统会为它分配地址空间。

       线程没有自己独立的地址空间,线程共享进程中的数据,使用相同的地址空间。每个线程都有自己的堆栈。

       线程切换的资源开销要比进程小。涉及频繁切换,就选择线程。

       线程开销小,但是不利于进行资源包含;进程开销大,但是有利于资源保护。

3、关于通信

线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。(ftok函数)

但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也跟着死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

4、执行过程

       每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

6.4 何时使用多进程,何时使用多线程?

       对资源的管理和保护要求高,不限制开销和效率时,使用多进程。

       要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。

6.5 进程的几种状态?

​关于IO:

       用户程序进行IO的读写,会用到read&write两大系统调用。read系统调用,是把数据从内核缓冲区复制到进程缓冲区;而write系统调用,是把数据从进程缓冲区复制到内核缓冲区

 同步IO

是指用户空间线程是主动发起IO请求的一方,内核空间是被动接受方。

       异步IO

是指内核kernel是主动发起IO请求的一方,用户线程是被动接受方。

6.6 进程创建的方式?

6.6.1 使用fork创建

       创建新进程在Linux的下是由父进程来完成的,创建完成的新进程是子进程。

       新进程的地址空间有两种可能性:

1、子进程是父进程的复制品(除了PID和task_struct是子进程自己的,其余的都从父进程复制而来

2、子进程装入另一个程序。

在Linux下的fork函数用于创建一个新的进程,使用fork函数来创建一个进程时,子进程只是完全复制父进程的资源。​

6.6.2 fork和vfork的区别?

       void exit( int status) 结束当前进程并将status返回;exit结束进程会刷新缓冲区

       void _exit(int status)  这个不会进行缓冲区刷新

1. fork( )的子进程拷贝父进程的数据段和代码段;vfork( )的子进程与父进程共享数据段

2. fork( )的父子进程的执行次序不确定;vfork( )保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后父进程才可能被调度运行。

3. vfork( )保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。

4. 当需要改变共享数据段中变量的值,则拷贝父进程。

6.7 进程间通信方式有哪些?有什么优缺点?

6.7.1 管道(pipe)

       管道这种通讯方式有两种限制:

       一是半双工的通信,数据只能单向流动;

       二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

       缺点:速度慢,容量有限,只有父子进程能通讯。

6.7.2 流管道 s_pipe

       可以进行双向传输(全双工);允许具有亲缘关系进程间通信;也允许无亲缘关系进程间通信。

6.7.3 信号量

       信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

       缺点:只能用来同步,不能用来进行传递复杂信息。

6.7.4 消息队列

       容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题,消息队列可以不再局限于父子进程,而允许任意进程通过共享消息队列来实现进程间通信,并由系统调用函数来实现消息 发送和接收之间的同步,从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题,使用方便, 但是信息的复制需要额外消耗CPU的时间,不适宜于信息量大或操作频繁的场合。此种方法不太常用。

6.7.5 共享内存

       利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。共享内存块提供了在任意数量的 进程之间进行高效双向通信的机制。每个使用者都可以读取写入数据,但是所有程序之间必须达成并遵 守一定的协议,以防止诸如在读取信息之前覆写内存空间等竞争状态的出现。

6.8 线程创建方式

6.9 僵尸进程、孤儿进程、守护进程是什么?

       僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

       孤儿进程:父进程异常结束,子进程被进程Init所收养。

       守护进程:创建守护进程时,有意把父进程结束,然后被1号进程init收养

       区分:一个正常运行的子进程,如果此刻子进程退出,父进程没有及时调用wait或waitpid收回子进程的系统资源,该进程就是僵尸进程,如果系统收回了,就是正常退出,如果一个正常运行的子进程,父进程退出了但是子进程还在,该进程此刻是孤儿进程,被init收养,如果父进程是故意被杀掉,子进程做相应处理后就是守护进程

6.10 僵尸进程的危害?

        在进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号PID,退出状态,运行时间等)。直到父进程通过wait / waitpid 来取时才释放。 如果进程不调用 wait / waitpid 的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程。

6.11 如何清理僵尸进程?

       当系统中出现了僵尸进程时,我们是无法通过 kill 命令把它清除掉的。但是我们可以杀死它的父进程, 让它变成孤儿进程,并进一步被系统中管理孤儿进程的进程收养并清理。  

#秋招##嵌入式##嵌入式笔面经分享#

我打算把自己整理的八股文笔记、面试经验、项目经验、简历修改经验等等,分享给大家。之前准备找工作那会,很多付费的东西,质量参差不齐,我打算在牛客创建一个免费的专栏,分享整理的这些内容,今天这个是第一篇文章,对于找工作的人提供一份帮助就行。

全部评论

相关推荐

好像是有一个考试的,考完了之后很早就进入面试中的流程了,到9.23左右才约面,最后约的9.26一面:1. 自我介绍2. IIC总线3. UART、IIC、SPI、CAN的对比4. 为什么要有Linux系统,怎么看到总线驱动设备这么一套框架5. Linux是怎么去找驱动的6. Linux驱动具体做过些什么7. 具体怎么做Linux驱动开发8. Linux和RTOS的内存管理9. 具体Linux里面是怎么分配内存的10. 怎么映射地址的11. TLB知道吗,具体的虚拟地址到物理地址,怎么找到的,怎么分配的12. 内存分配的算法13. 知道best fit吗?14. 怎么看待内存碎片,怎么合并15. 怎么减少内存碎片的出现16. 是否有办法做到内存碎片不出现17. Linux怎么做内存管理的,跟RTOS有什么区别18. Linux对内存是否有优化的管理算法19. 文件系统20. 进程线程21. 锁的简单理解22. 中断里能不能用互斥锁(这个不太会,但答案是知道的是不行,可以用自旋锁)23. volatile关键字(这个被拷打了很久,我记得是直接从内存读取,但面试官说我说反了,这个我纠结了很久)24. CPU怎么调用函数的25. 函数如何传参26. 内存怎么分配的,会分配成什么样子27. 变量会存在内存的哪里28. 有用过yolo,知道些什么,是否考虑做算法29. 系统启动的具体流程(最后说了STM32的启动过程)30. ST从FLASH启动,为什么是0x08000000(留给SRAM和其他内部RAM)31. 经典反问业务就是做一些芯片的底层开发,也有协议开发,是一个非常大的部门,跟硬件相关的都在这个部门内去完成。一共三面,然后等通知。#秋招##嵌入式##通信硬件人笔面经互助#
查看31道真题和解析 通信硬件人笔面经互助
点赞 评论 收藏
分享
1. this指针是什么?它有什么作用?2. const成员函数有什么特点?如何使用?3. 如何实现一个简单的动态数组?4. enum和enum class有什么区别?5. nullptr是什么?它与NULL有何不同?6. 如何处理内存泄漏?请给出几种方法。7. 解释一下数据库的ACID特性。8. 什么是死锁?如何避免死锁?9. 解释一下链表和数组的区别。10. 什么是哈希表?它的优缺点是什么?11. 如何使用SQL进行数据查询?请给出示例。12. 什么是索引?它如何提高数据库查询性能?13. 解释一下进程和线程的区别。14. 什么是操作系统的中断机制?15. 解释一下二叉树的遍历方式。16. 如何实现一个简单的栈?17. 什么是数据库范式?请简要说明第一范式和第二范式。18. 解释一下内存管理中的堆和栈的区别。19. 什么是SQL注入?如何防止它?20. 解释一下快速排序和归并排序的基本原理。21. 什么是视图(View)?它有什么用?22. 如何使用std::vector实现动态数组?23. 什么是事务?如何实现事务的提交和回滚?24. 解释一下操作系统中的调度算法。25. 如何实现一个简单的图结构?26. 什么是外键?它的作用是什么?27. 解释一下深度优先搜索和广度优先搜索的区别。28. 什么是存储过程?它有什么优缺点?29. 如何处理数据库中的并发访问?30. 解释一下LRU缓存算法的基本原理。我面试看的是大佬的面经,链接放下边了  c++/嵌入式面经专栏-牛客网 https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM
点赞 评论 收藏
分享
7 27 评论
分享
牛客网
牛客企业服务