既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
进程是操作系统中的核心概念,它使得操作系统能够同时运行多个任务,并提供了资源管理和任务调度的基础。
并行和并发
在操作系统中,并行(Parallel)和并发(Concurrent)是两个重要的概念,它们描述了多个任务同时执行的方式。
并行是指两个或多个任务在同一时刻同时执行,每个任务都在自己的处理器核心上独立运行。在并行执行中,多个任务可以在不同的处理器上同时进行,从而实现更高的处理能力和效率。并行处理通常用于并行计算、多核处理器等场景。
并发是指两个或多个任务在一段时间内交替执行,虽然任务可能不是同时发生的,但给人的感觉是同时执行的。在并发执行中,任务之间通过操作系统的调度算法分时共享处理器,并以快速的时间片轮转方式进行切换。并发处理通常用于提高系统的响应性、资源利用率和任务间的交互。
总结一下并行和并发的区别:
- 并行:多个任务在同一时刻同时执行,每个任务独立运行在自己的处理器核心上,实现高效的同时处理能力。
- 并发:多个任务在一段时间内交替执行,通过时间片轮转方式进行切换,实现快速的任务切换和资源共享。
需要根据具体的场景和需求来选择并行还是并发方式,以充分利用系统资源、提高处理能力和响应性。
进程的状态
一个进程的活动期间应该具备五种基本状态,即创建状态、运行状态、就绪状态、阻塞状态、结束状态
- NULL -> 创建状态:一个新进程被创建时的第一个状态;
- 创建状态 -> 就绪状态:当进程被创建完成并初始化后,一切就绪准备运行时,变为就绪状态,这个过程是很快的;
- 就绪态 -> 运行状态:处于就绪状态的进程被操作系统的进程调度器选中后,就分配给 CPU 正式运行该进程;
- 运行状态 -> 结束状态:当进程已经运行完成或出错时,会被操作系统作结束状态处理;
- 运行状态 -> 就绪状态:处于运行状态的进程在运行过程中,由于分配给它的运行时间片用完,操作系统会把该进程变为就绪态,接着从就绪态选中另外一个进程运行;
- 运行状态 -> 阻塞状态:当进程请求某个事件且必须等待时,例如请求 I/O 事件;
- 阻塞状态 -> 就绪状态:当进程要等待的事件完成时,它从阻塞状态变到就绪状态;
进程的控制结构
在操作系统中,是用进程控制块(PCB)数据结构来描述进程的。PCB是进程存在的唯一标识
PCB包含什么信息
- 进程描述信息
- 进程控制和管理信息
- 资源分配清单
- CPU相关信息
每个PCB通常通过链表的方式进行组织,把具有相同状态的进程链在一起,组成各种队列。
进程上下文切换
在操作系统中,进程上下文切换是指从一个正在运行的进程切换到另一个就绪态的进程,使得另一个进程可以继续执行。上下文切换发生的时候,操作系统会保存当前进程的状态(上下文),包括寄存器的值、程序计数器、堆栈指针和其他相关信息,并加载下一个进程的状态,以便让其继续执行。
进程上下文切换的过程包括以下步骤:
- 保存当前进程的上下文:操作系统会保存当前进程的寄存器状态、程序计数器和其他相关寄存器的值,以及进程的堆栈指针等信息。
- 切换到目标进程:操作系统根据调度算法选择下一个要执行的进程,并加载该进程的上下文。这包括恢复目标进程的寄存器状态、程序计数器和堆栈指针等。
- 更新内核数据结构:操作系统会更新内核的进程控制块(PCB)等数据结构,记录进程切换的相关信息。
- 执行目标进程:操作系统将控制权转移到目标进程,使其开始执行。
进程上下文切换是操作系统实现进程调度和并发执行的重要机制。它允许多个进程在一个处理器上交替执行,实现并发性和共享资源。然而,上下文切换也会带来一定的开销,包括保存和恢复进程的上下文、更新数据结构等,因此需要在性能和响应性之间进行权衡。优化上下文切换的方式包括减少切换次数、减少上下文保存的数据量等。
进程上下文切换发生的场景
进程上下文切换在以下几种情况下会发生:
- 抢占式调度:当操作系统采用抢占式调度算法时,可能会在一个进程被抢占(被更高优先级的进程取代)时发生上下文切换。这可以是由于时间片用完、高优先级进程就绪或中断事件发生等原因。
- 阻塞和唤醒:当进程请求某个事件(如等待 I/O 完成)而无法继续执行时,操作系统会将该进程阻塞,并将 CPU 分配给另一个就绪态的进程。当等待的事件完成后,操作系统会将进程唤醒,并进行上下文切换,使其继续执行。
- 多任务环境切换:当操作系统运行多个任务时,通过时间片轮转或优先级调度等方式,会在进程之间进行切换,以实现并发执行。这种情况下,操作系统会周期性地进行上下文切换,以平衡各个任务的执行和资源利用。
- 中断处理:当发生硬件中断或软件中断(如系统调用)时,操作系统会暂停当前进程的执行,保存其上下文,并切换到中断处理程序。中断处理程序执行完后,操作系统会恢复先前被中断的进程的上下文,使其继续执行。
需要注意的是,进程上下文切换是一种开销较高的操作,因为它涉及到保存和恢复大量的寄存器状态和内核数据结构。因此,在设计和优化系统时,需要合理选择调度算法、减少上下文切换次数,以提高系统的性能和响应性。
进程的通信方式
在操作系统中,进程之间可以通过多种方式进行通信,以实现数据交换、共享资源和协作完成任务。常见的进程通信方式包括:
- 管道(Pipe):管道是一种半双工的通信方式,适用于有亲缘关系的进程间通信。它可以在父子进程或兄弟进程之间传递数据,通常用于单向通信。
- 命名管道(Named Pipe):命名管道是一种有名字的管道,可以在无亲缘关系的进程之间进行通信。不同于管道,命名管道可以在不同的进程间共享数据。
- 信号(Signal):信号是一种异步通信机制,用于通知进程发生了某个事件。进程可以通过发送信号给其他进程,来请求某种操作或通知其发生的事件。
- 共享内存(Shared Memory):共享内存是一种高效的进程间通信方式,允许多个进程直接访问同一块内存区域。进程可以通过读写共享内存来进行数据交换。
- 消息队列(Message Queue):消息队列是一种通过消息传递进行进程间通信的方式。进程可以将消息发送到消息队列中,其他进程可以从队列中获取消息。
- 信号量(Semaphore):信号量是一种用于进程同步和互斥的机制。通过对信号量的操作,进程可以控制对共享资源的访问。
- 套接字(Socket):套接字是一种网络编程中常用的通信方式,允许不同主机上的进程进行通信。它提供了一种标准化的接口,支持进程间的数据传输和网络通信。
这些进程通信方式各有特点,适用于不同的场景和需求。在选择进程通信方式时,需要考虑进程间的关系、数据量、性能要求和安全性等因素。
线程
什么是线程
线程是进程当中的一条执行流程,是CPU调度的最小单位。
线程的优缺点
线程的优点:
- 一个进程中可以同时存在多个线程;
- 各个线程之间可以并发执行;
- 各个线程之间可以共享地址空间和文件等资源;
线程的缺点:
- 当进程中的一个线程崩溃时,会导致其所属进程的所有线程崩溃(这里是针对 C/C++ 语言)
进程线程的区别
进程和线程是操作系统中的两个重要概念,它们有以下区别:
- 定义:进程是正在执行的程序的实例,是资源分配和调度的基本单位。线程是进程内部的执行单元,是进程的一个独立执行流。
- 资源和隔离:每个进程都有独立的地址空间、文件描述符、堆栈等资源,进程之间相互隔离。而线程是共享进程的资源,包括内存空间、文件描述符等。线程之间可以直接访问和共享数据,需要注意同步和互斥。
- 创建和切换开销:创建进程需要分配独立的资源和建立相应的数据结构,开销较大。而创建线程的开销较小,因为线程共享进程的资源,只需要分配线程控制块。线程的切换开销也较小,因为它们共享进程的地址空间和其他资源。
- 并发性:进程是操作系统分配资源和调度任务的基本单位,可以并发执行多个进程。而线程是进程内部的执行单元,多个线程可以在同一进程中并发执行。
- 通信和同步:进程之间通信需要使用进程间通信(IPC)机制,如管道、消息队列、共享内存等。线程之间可以通过共享内存、信号量、互斥锁等机制进行通信和同步。
- 失败影响:一个进程的失败通常不会影响其他进程。而一个线程的失败会导致整个进程的失败。
需要根据具体的应用需求和系统特点来选择使用进程还是线程。进程适合于独立的任务和资源隔离,线程适合于并发执行和共享的任务。多线程编程可以提高系统的性能和响应性,但同时也需要注意线程间的同步和互斥,避免竞态条件和数据不一致的问题。
线程的上下文切换
- 当两个线程不是属于同一个进程,则切换的过程就跟进程上下文切换一样;
- 当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据;
在操作系统中,线程上下文切换是指从一个正在执行的线程切换到另一个就绪态的线程,以便让另一个线程继续执行。线程上下文切换涉及保存当前线程的上下文,并加载下一个线程的上下文。
线程上下文切换的过程包括以下步骤:
- 保存当前线程的上下文:操作系统会保存当前线程的寄存器状态、程序计数器和其他寄存器的值,以及线程的堆栈指针等信息。
- 切换到目标线程:操作系统根据调度算法选择下一个要执行的线程,并加载该线程的上下文。这包括恢复目标线程的寄存器状态、程序计数器和堆栈指针等。
- 更新内核数据结构:操作系统会更新内核的线程控制块(TCB)等数据结构,记录线程切换的相关信息。
- 执行目标线程:操作系统将控制权转移到目标线程,使其开始执行。
线程上下文切换是操作系统实现多线程并发执行的重要机制。它允许多个线程在同一进程中交替执行,实现并发性和共享资源。然而,上下文切换也会带来一定的开销,包括保存和恢复线程的上下文、更新数据结构等,因此需要在性能和响应性之间进行权衡。优化上下文切换的方式包括减少切换次数、减少上下文保存的数据量等。
需要注意的是,线程上下文切换与进程上下文切换相比,开销较小,因为线程共享进程的资源和地址空间。因此,多线程编程可以更高效地利用系统资源,提高程序的性能和响应性。
线程的实现
- 用户线程:在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理
- 内核线程:在内核中实现的线程,是由内核管理的线程
- 轻量级线程:在内核中来支持用户线程
用户线程和内核线程的对应关系
- 一对一
- 多对一
- 多对多
用户线程如何理解、优缺点
用户线程是基于用户态的线程管理库来实现的,那么线程控制块(*Thread Control Block, TCB*) 也是在库里面来实现的,对于操作系统而言是看不到这个 TCB 的,它只能看到整个进程的 PCB。所以,用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等。
用户线程的优点:
- 每个进程都需要有它私有的线程控制块(TCB)列表,用来跟踪记录它各个线程状态信息(PC、栈指针、寄存器),TCB 由用户级线程库函数来维护,可用于不支持线程技术的操作系统;
- 用户线程的切换也是由线程库函数来完成的,无需用户态与内核态的切换,所以速度特别快;
用户线程的缺点:
- 由于操作系统不参与线程的调度,如果一个线程发起了系统调用而阻塞,那进程所包含的用户线程都不能执行了。
- 当一个线程开始运行后,除非它主动地交出 CPU 的使用权,否则它所在的进程当中的其他线程无法运行,因为用户态的线程没法打断当前运行中的线程,它没有这个特权,只有操作系统才有,但是用户线程不是由操作系统管理的。
- 由于时间片分配给进程,故与其他进程比,在多线程执行时,每个线程得到的时间片较少,执行会比较慢;
内核线程如何理解、优缺点
内核线程是由操作系统管理的,线程对应的 TCB 自然是放在操作系统里的,这样线程的创建、终止和管理都是由操作系统负责。
内核线程的优点:
- 在一个进程当中,如果某个内核线程发起系统调用而被阻塞,并不会影响其他内核线程的运行;
- 分配给线程,多线程的进程获得更多的 CPU 运行时间;
内核线程的缺点:
- 在支持内核线程的操作系统中,由内核来维护进程和线程的上下文信息,如 PCB 和 TCB;
- 线程的创建、终止和切换都是通过系统调用的方式来进行,因此对于系统来说,系统开销比较大;
轻量级线程如何理解
轻量级进程(*Light-weight process,LWP*)是内核支持的用户线程,一个进程可有一个或多个 LWP,每个 LWP 是跟内核线程一对一映射的,也就是 LWP 都是由一个内核线程支持,而且 LWP 是由内核管理并像普通进程一样被调度。在大多数系统中,LWP与普通进程的区别也在于它只有一个最小的执行上下文和调度程序所需的统计信息。
LWP 与用户线程的对应关系就有三种:
1 : 1
,即一个 LWP 对应 一个用户线程;N : 1
,即一个 LWP 对应多个用户线程;M : N
,即多个 LWP 对应多个用户线程;
调度
调度时机
以下状态的变化都会触发操作系统的调度:
- 从就绪态 -> 运行态:当进程被创建时,会进入到就绪队列,操作系统会从就绪队列选择一个进程运行;
- 从运行态 -> 阻塞态:当进程发生 I/O 事件而阻塞时,操作系统必须选择另外一个进程运行;
- 从运行态 -> 结束态:当进程退出结束后,操作系统得从就绪队列选择另外一个进程运行;
调度算法
- 非抢占式调度算法挑选一个进程,然后让该进程运行直到被阻塞,或者直到该进程退出,才会调用另外一个进程,也就是说不会理时钟中断这个事情。
- 抢占式调度算法挑选一个进程,然后让该进程只运行某段时间,如果在该时段结束时,该进程仍然在运行时,则会把它挂起,接着调度程序从就绪队列挑选另外一个进程。这种抢占式调度处理,需要在时间间隔的末端发生时钟中断,以便把 CPU 控制返回给调度程序进行调度,也就是常说的时间片机制。
调度原则
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
5897087733)]
[外链图片转存中…(img-73RxRApS-1715897087733)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!