C++后端操作系统面经(未完整,会一直更新)

本文详细解读了进程、线程和协程的概念,讨论了它们之间的关系,以及原子操作、临界资源、同步与异步、死锁等问题。重点介绍了Qt中的信号槽机制和多线程实现,强调了并发编程中的注意事项。
摘要由CSDN通过智能技术生成

进程,线程,协程

1、进程
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

2、线程
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

3、协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

**进程,线程,协程的关联:**线程包含于进程,协程包含于线程。只要内存足够,一个线程中可以有任意多个协程,但某一时刻只能有一个协程在运行,多个协程分享该线程分配到的计算机资源。

**原子操作:**一个函数(原语)或动作的指令序列不可分割,要么作为一个整体执行(不可中断),要么都不执行

**临界资源:**一次仅允许一个进程独占使用的不可剥夺的资源

**临界区:**进程访问临界资源的那段程序代码。一次仅允许一个进程在临界区中执行

**饥饿:**一个就绪进程被调度程序长期忽视、不被调度执行;一个进程长期得不到资源

阻塞与非阻塞:阻塞是指进程在发起了一个系统调用(System Call) 后, 由于该系统调用的操作不能立即完成,需要等待一段时间,于是内核将进程挂起为**等待 (waiting)**状态, 以确保它不会被调度执行, 占用 CPU 资源。非阻塞则相反。

同步和异步: 同步就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。异步是当一个过程调用发出后,调用者不能立刻得到结果,而是在调用发出后调用者可用继续执行后续操作,被调用者通过状体来通知调用者,或者通过回掉函数来处理这个调用。
同步就等价于去买东西,一直到完成付款拿到物品结束。异步就等于网购,只下单,签收。

**同步和互斥:**同步也称作制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为要在某些位置上协调它们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作关系。
互斥是指某一资源(临界资源,例如打印机、共享公共变量等)同时只允许一个访问者对其进行访问,具有唯一性和排它性。

同步的基本原则:
①忙则等待:当CPU有其他进程正在访问时,则需要进行等待,做到互斥,防止数据不一致
②空闲让进:当CPU空闲,就让进程进去使用CPU(让CPU忙起来=> 提高CPU利用率)
③有限等待:不能一直等待,这样便会出现饥饿死等现象,用户请求得不到响应
④让权等待:把CPU让给更加需要的请求进程去使用

**死锁:**死锁是指两个(多个)线程相互等待对方数据的过程,死锁的产生会导致程序卡死,不解锁程序将永远无法进行下去。(破坏其中一个条件即可预防死锁问题)
死锁产产生原因:①循环等待②不可抢占③请求和保持④互斥

解决死锁的方法:
①鸵鸟策略:当死锁不存在,忽略死锁
②死锁检测和死锁恢复:不试图阻止死锁,而是当检测到死锁发生时,采取措施进行恢复。利用抢占恢复,利用回滚恢复,通过杀死进程恢复。
③死锁预防:在程序运行之前预防发生死锁。
1)破坏互斥条件,例如假脱机打印机技术允许若干个进程同时输出,唯一真正请求物理打印机的进程是打印机守护进程。
2)破坏请求和保持条件,一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。
3)破坏不剥夺条件,允许抢占资源
4)破坏循环请求等待,给资源统一编号,进程只能按编号顺序来请求资源
④死锁避免:在程序运行时避免发生死锁。(安全检测,单个/多个资源银行家算法)

**中断:**通常被定义为一个事件,该事件能够改变处理器执行指令的顺序。这样的事件与 CPU 芯片内外部硬件电路产生的电信号相对应。中断分为同步中断和异步中断。

  • 同步中断——同步中断是当指令执行时由控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后 CPU 才会发出中断
  • 异步中断——异步中 断是由其他硬件设备依照 CPU 时钟信号随机 产生的。

常见的设计模式:

  1. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。优点是节省系统资源,提供了全局访问的统一入口;缺点是可能引入全局状态,增加了类的耦合性。

  2. 工厂模式(Factory Pattern):通过工厂类创建对象,隐藏对象的具体实现。优点是解耦了具体对象的创建和使用,提供了灵活性;缺点是增加了类的数量,可能导致系统复杂性增加。

  3. 观察者模式(Observer Pattern):定义了一种一对多的依赖关系,当一个对象状态发生改变时,其所有依赖者都会收到通知并自动更新。优点是解耦了观察者和被观察者,提供了一种松耦合的设计;缺点是可能导致性能问题,观察者过多时通知的开销较大。

  4. 装饰器模式(Decorator Pattern):动态地给一个对象添加额外的功能,是继承的一种替代方案。优点是灵活性高,可以动态地扩展对象的功能;缺点是可能导致类的数量增加,复杂性增加。

  5. 策略模式(Strategy Pattern):定义了一系列算法,将每个算法封装起来,使它们可以互相替换。优点是增加了代码的灵活性和可维护性,减少了代码重复;缺点是可能导致类的数量增加,复杂性增加。

  6. 适配器模式(Adapter Pattern):将一个类的接口转换成客户端所期望的另一个接口,使得原本不兼容的类可以一起工作。优点是增加了代码的复用性和灵活性;缺点是可能导致系统复杂性增加。

  7. 迭代器模式(Iterator Pattern):提供一种顺序访问聚合对象中各个元素的方法,而又不暴露其内部实现。优点是封装了聚合对象的遍历过程,提供了一种统一的访问方式;缺点是可能导致性能问题,遍历操作的开销较大。

信号和槽函数:
在Qt中,信号和槽是一种用于对象间通信的机制。信号是对象发出的一种特殊的函数,槽是接收信号并执行相应操作的函数。当信号被触发时,与之相连接的槽函数会被自动调用。
信号和槽的实现原理主要基于Qt的元对象系统(Meta-Object System)。在编译时,Qt的元对象编译器(MOC)会解析源代码中的信号和槽声明,并生成相应的元对象代码。
以下是信号和槽的实现原理的简要步骤:

  1. 定义信号和槽函数:在类的声明中,使用特殊的宏(如Q_SIGNALS、Q_SLOT等)来声明信号和槽函数。信号函数通常没有实现体,而槽函数可以有实现体。

  2. 元对象编译器(MOC)处理:在编译时,MOC会解析源代码中的信号和槽声明,并生成元对象代码。这些元对象代码包含信号和槽的相关信息,如函数指针、参数类型等。

  3. 元对象系统注册:在运行时,Qt的元对象系统会注册类的元对象信息。这些信息包括类名、父类、信号和槽的映射关系等。

  4. 信号和槽的连接:在代码中,使用QObject::connect()函数来建立信号和槽的连接。该函数需要指定信号发送者、信号函数指针、槽接收者、槽函数指针等参数。当信号被触发时,系统会根据连接关系自动调用相应的槽函数。

  5. 信号的触发:信号可以通过调用emit关键字来手动触发,也可以在特定条件下自动触发。当信号被触发时,系统会根据连接关系调用相应的槽函数。

需要注意的是,信号和槽的连接可以是跨线程的,Qt提供了线程安全的机制来处理线程间的信号和槽通信。

Qt多线程实现:
在Qt中,多线程可以通过以下步骤来实现:

  1. 声明一个继承自QObject的类,并在类中定义需要在新线程中执行的函数。
  2. 在该类中声明一个信号,用于在新线程中发送消息给主线程。
  3. 在主线程中创建一个QThread对象,并将上述类的实例移动到该线程中。
  4. 连接信号和槽,将信号连接到主线程中的槽函数,以便在新线程中发送的消息可以被处理。
  5. 启动新线程,通过调用QThread的start()函数来启动新线程的执行。

实现原理:
Qt的多线程机制是基于事件循环和信号槽机制的。当一个QObject对象被移动到一个新的线程时,它的事件循环也会被移动到该线程中。该线程会在自己的事件循环中处理事件和信号槽的连接。

当在新线程中调用QObject对象的函数时,实际上是通过事件机制将函数调用转发到新线程的事件循环中。新线程的事件循环会在适当的时候执行这些函数。

通过信号和槽的连接,可以在新线程中发射信号,然后在主线程中接收并处理这些信号。这样就实现了新线程和主线程之间的通信。

需要注意的是,在多线程编程中,需要注意线程安全性和共享资源的访问问题,以避免竞争条件和数据不一致的问题。可以通过互斥锁、条件变量等机制来保护共享资源的访问。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值