Day03

1. 简述一下虚函数的实现原理

  1. c++中虚函数的作用主要是实现了动态多态机制。动态多态,简单地说就是用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术
  2. 编译器处理虚函数时,给每个对象添加一个隐藏的成员。隐藏的成员是一个指针类型的数据,指向的是函数地址数组,这个数组被称为虚函数表。虚函数表中存储的是类中的虚函数地址。如果派生类重写了基类中的虚函数,则派生类对象的虚函数表中保存的是派生类的虚函数地址,如果派生类没有重写基类中的虚函数,则派生类对象的虚函数表中保存的是父类的虚函数地址
  3. 使用虚函数时,对于内存和执行速度方面会有一定的成本:
    • 每个对象都会变大,变大的量为存储虚函数表指针
    • 对于每个类,编译器都会创建一个虚函数表
    • 对于每次调用虚函数,都需要额外执行一个操作,就是到表中查找虚函数地址

2. 说一说进程通信的方式有哪些?

  1. 管道(匿名管道):本质上是内核中维护的一块内存缓冲区,Linux系统中由pipe()函数创建,只能用于具有亲缘关系的进程间通信
  2. 命名管道:不同于匿名管道之处在于它提供了一个路径名与之关联,进程通过访问该路径就能相互通信,适用于没有亲缘关系的进程间通信
  3. 信号:一种异步通信方式,信号可以让一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件
  4. 消息队列:是一个消息链表且随内核持续,具有特定的格式和特定的优先级,由具有写权限的进程添加消息,由具有读权限的进程读走消息
  5. 共享内存:允许两个或者多个进程共享物理内存的同一块区域(通常被称为段),无需内核介入,速度比管道快
  6. 内存映射:将磁盘文件映射到内存,用户通过修改内存就能修改磁盘文件
  7. 信号量:主要用来解决进程和线程间并发执行时的同步问题
  8. socket套接字:一般用于网络中不同主机上的进程之间的通信,且提供了应用层进程利用网络协议交换数据的机制

3. 说一说进程有多少种状态,如何转换

  1. 创建:一个进程启动,首先进入创建状态,需要获取系统资源创建进程管理块(PCB)完成资源分配
  2. 就绪状态:在创建状态完成之后,进程已经准备好,处于就绪状态,但是还未获得处理器资源,无法运行
  3. 运行状态:获取处理器资源,被系统调度,当具有时间片开始进入运行状态。如果进程时间片用完了就进入就绪状态
  4. 阻塞状态:在运行状态期间,如果进行了阻塞的操作,此时进程暂时无法操作就进入到了阻塞状态,在这些操作完成之后就进入了就绪状态。
  5. 终止状态:进程结束或者被系统终止,进入终止状态

4. 请你说说线程的通信方式

  1. 线程间无需特别的手段进行通信,因为线程间可以共享一份全局内存区域,其中包括初始化段、未初始化段、以及堆内存等,所以线程之间可以方便、快速地共享信息。只需要将数据复制到共享变量即可。
  2. 考虑到线程之间的同步互斥,应用到的技术有:
    1. 信号 linux使用pthread_kill()函数对线程发信号
    2. 互斥锁确保同一时间只能有一个线程访问共享资源,当锁被占用时试图对其加锁的线程都进入阻塞状态,当锁释放时哪个线程能获得该锁取决于内核的调度。
    3. 读写锁当以写模式加锁而处于写状态时任何试图加锁的线程(不论是读是写)都阻塞;当以读模式加锁而处于读状态时,“读线程“不阻塞,“写线程”阻塞。
    4. 自旋锁上锁受阻时线程不阻塞而是在循环中轮询查看能否获得该锁,没有线程的切换因而没有切换开销,不过对CPU的霸占会导致CPU资源的浪费。所以自旋锁适用于多个处理器的并行结构或者适用于被持有时间短而不希望在线程切换产生开销的情况
    5. 条件变量:条件变量可以以原子的方式阻塞线程,知道某个特定的条件为真。对条件的测试是在互斥锁保护下进行的,条件变量始终和互斥锁一起使用
    6. 信号量:信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。在公共资源增加的时候,信号量就增加;公共资源减少的时候,信号量就减少;只有当信号量的值大于0时,才能访问信号量锁代表的公共资源

5. 请你说说进程和线程的区别

  1. 进程有独立的地址空间,线程有自己的堆栈和局部变量,但线程没有单独的地址空间
  2. 进程和线程切换时,需要切换进程和线程的上下文,进程的上下文切换时间开销远远大于线程上下文切换时间,耗费资源较大,效率要差一些
  3. 进程的并发性不如线程
  4. 每个独立的进程有一个程序运行的入口、顺序执行的序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程控制支持
  5. 系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存,线程组之间只能共享资源
  6. 一个进程崩溃后,在保护模式下不会对其他进程尝试影响,但是一个线程崩溃,如果是对共享数据的破坏,则可能导致整个进程死掉,所以多进程要比多线程健壮

6. 请你说说线程和协程的区别

  1. 线程是操作系统的资源,线程的创建、切换、停止等都非常消耗资源,而创建协程不需要调用操作系统的功能,编程语言自身就能完成,所以协程也被称为用户态线程,协程比线程轻量很多
  2. 线程在多核环境下能够做到真正意义上的并行,而协程是为并发而产生的
  3. 一个具有多个线程的程序可以同时运行多个线程,而协程却需要彼此协作运行
  4. 线程进程都是同步机制,而协程则是异步机制
  5. 线程是抢占式的,而协程是非抢占式的,所以需要用户自己释放使用权来切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程能力
  6. 操作系统对于线程开辟数量限制在千的级别,而协程可以达到上万的级别
最后修改:2024 年 06 月 08 日
如果觉得我的文章对你有用,请随意赞赏