操作系统第二章(整理详细的知识点)(算法类问题单独写在其他文章)

第二章

1、进程的定义、组成、组织方式、特征

定义:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
组成: PCB、程序段、数据段
PCB:进程的描述信息、进程控制和管理信息、资源分配清单、处理相关信息。
程序段:存放要执行的程序代码
数据段:存放程序运行过程中的各种数据。
组织形式:链接方式、索引方式
链接方式:按进程状态将PCB分为多个队列
索引方式:按进程状态建立几张索引表,各表项指向一个PCB
特征: 动态性、并发性、独立性、异步性、结构性
动态性:进程的基本特征
独立性:进程是系统进行资源分配,调度的独立单位
异步性:各进程以不可预知的速度向前推进,可能导致运行结果的不确定性。

进程的状态与转换

进程的状态: 运行状态、就绪状态、阻塞状态、创建状态、终止状态
运行状态:有CPU,有其他所需资源
就绪状态:无CPU,有其他所需资源
阻塞状态:无CPU,无其他所需资源
创建状态:操作系统为新进程分配资源,创建PCB
终止状态:操作系统回收进程的资源、撤销PCB
进程状态间的转换:
就绪态—>运行态:进程被调度
运行态—>就绪态:时间片到,或CPU被其他优先级的进程抢占
运行态—>阻塞态:等待系统资源分配,或等待某事件发生
阻塞态—>就绪态:资源分配到位,等待的事件发生
创建态—>就绪态:系统完成创建进程相关的工作
进行态—>终止态:进程运行结束,或运行过程中遇到不可修复的错误

2、进程控制

进程控制就是要实现进程状态转换
用原语实现进程控制。原语的特点是执行期间不允许中断,只能一气呵成。
这种不可断的操作被即原子操作。
原语采用关中断指令开中断指令实现
关/开中断指令的权限非常大,是只允许在核心态下执行的特权指令
进程的创建:
创建原语:
申请空白PCB—>为新进程分配所需资源—>初始化PCB—>将PCB插入就绪队列 (无—>创建态—>就绪态)
引起进程创建的事件:
用户登录:分时系统中,用户登录成功,系统会建立为其建立一个新的进程
作业调度:多道批处理系统中,有的作业放入内存时,会为其建立一个新的进程
提供服务:用户向操作系统提出某些请求时,会建立一个进程处理该请求
应用请求:由用户进程主动请求创建一个子进程
进程的终止
撤销原语:(就绪态/阻塞态/运行态—>终止态—>无)
1 从PCB集合中找到终止进程的PCB
2 若进程正在运行,立即剥夺CPU,将CPU分配给其他进程
3 终止其所有子进程
4 将该进程拥有的所有资源归还给父进程或操作系统
5 删除PCB

引起进程终止事件:
正常结束 异常结束 外界干预

进程的阻塞和唤醒
阻塞原语唤醒原语必须成对使用
进程的阻塞:(运行态—>阻塞态)
阻塞原语
1 找到要阻塞的进程对应的PCB
2 保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行
3 将PCB插入相应事件的等待队列

引起进程阻塞的事件:
需要等待系统分配某种资源
需要等待相互合作的其他进程完成相关工作

进程的唤醒:(阻塞态—>就绪态)
唤醒原语:
1 在事件等待队列中找到PCN
2 将PCB从等待队列移除,设置进程为就绪态
3 将PCB插入就绪队列,等待被调度
引起进程唤醒的事件:等待的事件发生

进程的控制的相关原语
切换原语:
1 将运行环境信息存入PCB
2 PCB移入相关队列
3 选择另一个进程执行,并更新其PCB
4 根据PCB恢复新进程所需的运行环境

引起进程切换的事件:
当前进程时间片到
有更高优先级的进程到达
当前进程主动阻塞
当前进程终止

进程控制就是要实现进程状态的转换
进程控制用原语实现(原语用关/开中断实现、原语是一种特殊的程序、原语的执行必须一气呵成、不可中断)

相关原语:进程的创建,进程的终止,进程的阻塞,进程的唤醒,进程的切换 (阻塞和唤醒要成对出现)

3、进程通信

顾名思义,进程通信就是指进程之间的信息交换。
进程是分配系统资源的单位(包含内存地址空间),因此各进程拥有的内存地址空间相互独立。
为了保证安全,一个进程不能直接访问另一个进程的地址空间。
但是进程之间的信息交换又是必须实现的。为了保证进程间的安全通信,操作系统提供了一些方法。
进程通信:共享存储 消息传递 管道通信

共享存储:基于数据结构的共享和基于存储区的共享
两个进程对共享空间的访问必须是互斥的(互斥访问通过操作系统提供的工具实现)
操作系统只负责提供共享空间和同步互斥工具(如P V操作)

基于数据结构的共享:比如共享空间里面只能放一个长度为10的数组。这种共享方式速度慢、限制多、是一种低级通信方式。

基于存储区的共享:在内存中画出来一块共享存储区,数据的形式、存放位置都由进程控制,而不是操作系统。相比之下,速度更快,是一种高级通信方式

管道通信
1 管道通信只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道
2 各进程要互斥地访问管道。
3 数据以字符流的形式写入管道,当管道写满时。写进程的write()系统调用将被阻塞,等待读进程将数据取走。当读进程将数据全部取走后,管道变空,此时==读进程的read()==系统调用将被阻塞。
4 如果没写满,就不允许读。如果没读空,就不允许写。
5 数据一旦被读出,就从管道中被抛弃,这就意味着读进程最多只能有一个,否则可能会有读错数据的情况。

消息传递
进程间的数据交换以格式化的消息为单位。进程通过操作系统提供的“发送消息/接受消息”两个原语进行数据交换。

共享存储:
设置一个共享空间
要互斥的访问共享空间
两种方式(基于数据结构 基于存储区的共享 )

管道通信:
设置一个特殊的共享文件(管道),其实就是一个缓冲区
一个管道只能实现半双工通信
实现双向同时通信要建立两个管道
各进程要互斥的访问管道
写满时,不能再写,读空时,不能再读
没写满,不能读,没读空,不能写

消息传递:
传递结构化的消息(消息头/消息体)
系统提供“发送/接受邀请”
两种方式;
直接通信方式:消息直接挂到对方的接受队列里
间接通信方式:消息先发到中间体

4、线程概念和多线程模型

什么是线程。为什么要引入线程?
在没引入进程之前,系统中各个程序只能串行执行。
进程是程序的一次执行。但是这些功能显然不是一个程序顺序处理就能实现的。
有的进程可能需要“同时”做很多事,而传统的进程只能串行地执行一系列程序。为此,引入了“线程”,来增加并发度
传统的进程是程序执行流的最小单位,引入了线程之后,线程成为了程序执行流的最小单位
可以把线程理解为“轻量级进程”。线程是一个基本的CPU执行单元,也是程序包执行流的最小单位
引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务。

引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)
引入线程机制后,有什么变化?
资源分配,调度:传统进程机制中,进程是资源分配、调度的基本单位,引入线程后,进程是资源的分配单位,线程是调度的基本单位
并发性:传统进程机制中,只能进程间并发;引入线程后,各线程间也能并发,提升了并发度
系统开销: 传统的进程间并发,需要切换进程的运行环境,系统开销很大;线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小。引入线程后,并发所带来的系统开销减小。
线程的属性
线程是处理机调度的单位
多CPU计算机中,各个线程可占用不同的CPU
每个线程都有一个线程ID、线程控制块(TCB)
线程也有就绪、阻塞、运行三种基本状态
线程几乎不拥有系统资源
同一进程的不同线程共享进程的资源
由于共享内存空间地址,同一进程中的线程间通信甚至不需要系统干预
同一进程中的线程切换,不会引起进程切切换
不同进程中的线程切换,会引起进程切换
切换同进程的线程,系统开销很小
切换进程,系统开销较大
线程的实现方式
用户级线程:
用户级线程由应用程序通过线程库实现。所有的线程管理工作都由应用程序负责(包括线程切换)
用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。
在用户来看,是有多个线程。但是在操作系统内核来看,并意识不到线程的存在。(用户级线程对用户不透明,对操作系统透明)
可以这样理解,用户级线程就是从用户视角看能看到的线程。

内核级线程:
内核级线程的管理工作操作系统内核完成。线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成
可以这样理解,内核级线程就是从操作系统内核视角看能看到的线程。

线程的实现方式:在同时支持用户级线程和内核级线程的系统中,可采用二者组合的方式:将n个用户级线程映射到m和内核级线程上(n>=m)。

重点
操作系统只分配看得见的内核级线程,因此只有 内核级线程才是处理机分配的单位。

多线程模型:
在同时支持用户级线程和内核级线程的系统中,由几个用户级线程线程映射到几个内核级线程的问题引出来“多线程模型”。

  • 多对一模型:多个用户极线程只能映射到一个内核级线程。每个用户进程只对应一个内核级线程。
    优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小、效率高
    缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
  • 一对一模型:
    一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程相同数量的内核级线程
    优点:当一个线程被阻塞之后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并发执行。
    缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内盒完成,需要切换到核心态,因此线程管理的成本高,开销大。
  • 多对多模型:
    n用户级线程映射到m个内核级线程(n>=m)。每个用户级线程对应m个内核级线程、
    客服了多对一模型并发度不高的缺点,又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。

什么是线程。为什么要引入线程?
可以理解为“轻量级进程”
可增加并发度,减少并发带来的开锁
引入线程后,有什么变化?(和传统的进程相比)
资源分配,处理机调度
并发性
(实现并发的)系统开锁
线程有哪些重要的属性
线程是处理机调度的单位,进程是资源分配的单位
同一进程的各线程共享进程拥有的资源
同一进程内的线程切换不会导致进程切换
线程实现方式?
用户级线程:从用户视角看的线程
内核级线程:从操作系统视角看的进程(内核级线程才是处理机分配的单位)
组合方式:上述两种方式的结合
多线程模型
多对一模型:
优:进程管理开销小效率高
缺:一个线程阻塞会导致整个进程都被阻塞(并发度低)
一对一模型:
优:进程管理开销大
缺:各个线程可分配到多核处理机并行执行,并发度高
多对多模型:
集二者所长

5、处理机调度的概念、层次

处理机调度 :基本概念 三个层次、三层调度的联系、对比 补充知识

5.1 调度的基本概念

当有一堆任务要处理,但由于资源有限,这些事情没法同时处理,这就需要确定某种规则来决定处理这些任务的顺序,这就是调度研究的问题。
在多道程序系统中,进程的数量往往是多余处理机的个数的,这样不可能同时并行地处理各个进程。处理机调度,就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程的并发执行

5.2 调度的三个层次

由于内存空间有限,有时无法将用户提交的作业全部放入内存,因此就需要确定某种规则来决定将作业调入内存的顺序。
高级调度(作业调度):按一定的规则从外存上处于后备队列的作业中挑选一哥(或多个作业),给他们分配内等必要资源,并建立相关的进程(建立PCB),以使它(们)获得竞争处理机的权利。
高级调度是辅存(外存)与内存之间的调度。每个作业只调入一次,调出一次。作业调入时会建立相应的PCB,作业调出时才撤销PCB。 高级调度主要是指调入的问题,因为只有调入的实际需要操作系统来确定,但调出的时机必然是作业运行结束才调出。
中级调度(内存调度): 引入了虚拟存储技术之后,可将暂时不能运行的进程调至外存等待。等它重新具备了运行条件且内存又稍有空闲时,再重新调入内存。
这么做的目的是为了提高内存利用率系统吞吐量
暂时调到外存等待的进程成为挂起状态。值得注意的是,PCB并不会一起调到外存,而是会常驻内存。PCB中会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的PCB来保持对各个进程的监控、管理。被挂起的进程PCB会被放到挂起队列中
中级调度(内存调度),就是要决定将哪个处于挂起状态的进程重新调入内存。
低级调度(进程调度):其主要任务是按照某种方法和策略从就绪队列中选取一个进程,将处理机分配给它。
进程调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度。
进程调度的频率很高,一般几十毫秒一次。

  • 调度的基本概念:按某种算法选择一个进程将处理机分配给它

  • 三个层次

    • 高级调度(作业调度):按照某种规则,从后备队列中选择合适的作业将其调入内存,并为其创建进程
    • 中级调度(内存调度):按照某种规则,从挂起队列中选择合适的进程将其数据调回内存
    • 低级调度(进程调度):按照某种规则,从就绪队列中选择一个进程为其分配处理机
  • 三层调度的联系、对比

    • 高级调度:内存–>外存(面向作业) 发生频率最低
    • 中级调度:外存–>内存(面向进程) 发生频率中等
    • 低级调度:内存–>CPU 发生频率最高

6、进程调度的时机、切换与过程、方式

6.1进程调度的时机、切换

进程调度(低级调度), 就是按照某种算法从就绪队列中选择一个进程为其分配处理机。
需要进行进程调度与切换的情况:当前运行的进程主动放弃处理机,当前运行的进程被动放弃处理机
当前运行的进程主动放弃处理机:
1 进程正常终止
2 运行过程中发生异常而终止
3 进程主动请求阻塞
当前运行的进程被动放弃处理机:
1 分给进程的时间片用完
2 有更紧急的事需要处理(如I/O中断)
3 有更高优先级的进程进入就绪队列

不能进行进程调度与切换的情况:
1 在处理中断的过程中,中断处理过程复杂,与硬件密切相关,很难做到在中断处理过程中进行进程切换
2 进程在操作系统内核程序临界区中
3 在原子操作过程中(原语)。原子操作不可中断,要一气呵成。

进程在操作系统内核程序临界区不能进行调度与切换。
临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。
临界区:访问临界资源的那段代码
内核程序临界区一般用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的PCB组成)

内核程序临界区访问的临界资源如果不尽快释放的画,极有可能影响到操作系统内核的其他管理工作。因此在访问内核程序临界区期间不能进行调度与切换。

普通临界区访问的临界资源不会直接影响操作系统内核的管理工作。因此在访问普通临界区时可以进行调度与切换。

6.2 进程调度的方式

**非剥夺调度方式,又称非抢占方式。**即,只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止或主动要求进入阻塞态。(实现简单,系统开销小但是无法及时处理紧急任务,适合于早期的批处理系统)

剥夺调度方式,又称抢占方式: 当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停长在执行的进程,将处理机分配给更重要紧迫的那个进程(可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能。适合于分时操作系统、实时操作系统)

6.3 进程的切换与过程

“狭义的进程调度”与“进程切换的区别”:
狭义的进程调度指的是从就绪队列中选中一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程,也可能是另一个进程,后一种情况就需要进程切换

广义的进程调度包含了选择一个进程和进程切换两个步骤。

进程切换的过程主要完成了:
1 对原来运行进程各种数据的保存
2 对新的进程各种数据的恢复

注意:进程切换是有代价的,因此如果过于频繁的进行进程调度、切换,必然会使整个系统的效率降低,使系统大部分时间都花在了进程切换上,而真正用于执行进程的时间减少、

第六总结:
时机:
什么时候需要进程调度:

  • 主动放弃
    • 进程正常终止
    • 运行过程中发生异常而终止
    • 主动阻塞(如 等待I/O)
  • 被动放弃
    • 分给进程的时间片用完
    • 有更紧急的事情需要处理
    • 有更高优先级的进程进入就绪队列

什么时候不能进行进程调度

  • 在处理中断的过程中
  • 进程在操作系统内核程序临界区中
  • 原子操作过程中(原语)

切换与过程

  • 狭义的“调度”和“切换的区别”
  • 切换过程
    • 对原来运行进程各种数据的保存
    • 对新的进程各种数据的恢复
  • 结论:进程调度、切换是有代价的,并不是调度越频繁,并发度就越高

方式

  • 非剥夺调度方式(非抢占式):只能由当前运行的进程主动放弃CPU
  • 剥夺调度方式(抢占式):可由操作系统剥夺当前进程的CPU使用权

7 调度算法的评价指标

CPU利用率:指CPU“忙碌”的时间占总时间的比例。
利用率=忙碌的时间 / 总时间

系统吞吐量:单位时间内完成作业的数量
系统吞吐量=总共完成了多少道作业 / 总共花了多少时间

周转时间:是指用户从作业被提交给系统开始,作业完成为止的这段时间间隔
周转时间=作业完成时间-作业提交时间
平均周转时间=各作业周转时间之和 / 作业数
带权周转时间=作业周转时间 / 作业实际运行的时间=(作业完成时间-作业提交时间)/ 作业实际运行的时间
对于周转时间相同的两个作业,实际运行时间长的作业在相同时间内被服务的时间更多,带权周期时间更小,用户满意度更高
对于实际运行时间相同的两个作业,周转时间短的带权周转时间更小,用户满意度更高
平均带权周转时间=各作业带权周转时间之和 / 作业数

等待时间:指进程/作业处于等待处理机状态时间之和
等待时间越长,用户满意度越低。

  • 对于进程来说,等待时间是指进程建立后等待被服务的时间之和,在等待I/O完成的期间其实进程也是在被服务的,所以不计入等待时间
  • 对于作业来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间

-响应时间:指从用户提交请求首次产生产生响应所用的时间。

8、FCFS 、SJF、HRRN调度算法

FCFS:https://blog.csdn.net/m0_47642376/article/details/107892828
SJF:https://blog.csdn.net/m0_47642376/article/details/107895482
HRRN :https://blog.csdn.net/m0_47642376/article/details/107957959

9、调度算法

10、进程同步、进程互斥

10.1 进程同步

同步也称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作持续而产生的制约关系。进程的直接制约关系就是源于它们之间的相互合作。

并发性带来了异步性,有时也需要通过进程同步解决这种异步问题
有的进程之间需要相互配合地完成工作,各进程的工作推进需要遵循一定的先后顺序

10.2 进程互斥

两种资源共享方式:

  • 互斥共享方式:系统中的某些资源,虽然可以提供个多个进程使用,但一个时间段内只允许一个进程访问该资源
  • 同时共享方式:系统中的某些资源,允许一个时间段内由多个进程“同时”对它们进行访问

我们把一个时间段内只允许一个进程使用的资源成为临界资源。许多物理设备(比如摄像头,打印机)都是临界资源。此外还有许多变量,数据,内存缓冲区等都属于临界资源

对临界资源的访问,必须互斥的进行。互斥,也称间接制约关系。进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源

对临界资源的访问,需要互斥的进行,即同一段时间内只能允许一个进程访问的资源

四个部分

  • 进入区:检查是否可以进入临界区,若可进入,需要“上锁”
  • 临界区:访问临界资源的那段代码
  • 退出区:负责解锁
  • 剩余区:其余代码部分

需要遵循的原则:

  • 空闲让进:临界区空闲时,应允许一个进程访问
  • 忙则等待:临界区正在被访问时,其他试图访问的进程需要等待
  • 有限等待:要在有限时间内进入临界区,保证不会饥饿
  • 让权等待:进步了临界区的进程,要我释放处理机,防止忙等

对临界资源的互斥访问,可以在逻辑上分为如下四个部分

do{
	entry section;     //进入区
	critical section;  //临界区
	exit section;      //退出区
	remainder section; //剩余区
}
  • 进入区:负责检查是都可以进入临界区
  • 临界区:访问临界资源的那段代码
  • 退出区:负责解除正在访问临界资源的标志
  • 剩余区:做其他标志

注意:临界区是进程中访问临界资源的代码段
进入区退出区负责实现互斥的代码段

11、进程互斥的软件实现办法

单标志法:
1 在进入区只做“检查”,不“上锁”。
2 在退出区把临界区的使用权交给另一个进程(相当于在退出区给另一进程“解锁”,又给自己“上锁”)
3 主要问题:不遵循“空闲让进”原则

双标志先检查法:

  • 在进入区先“检查”后“上锁”,退出区“解锁”
  • 主要问题:不遵循“忙则等待”原则

双标志后检查法:

  • 在进入区先“加锁”后“检查”,退出区“解锁”
  • 主要问题:不遵循“空闲让进、忙则等待”原则,可能会导致饥饿

Peterson算法:

  • 在进入区“主动争取–主动谦让–检查对方是否想让进、已方是否谦让”
  • 主要问题:不遵循“让权等待”原则,会发生忙等
12、信号量控制

整型信号量:

  • 用一个整数型变量作为信号量,数值表示某种资源数
  • 整型信号量与普通整数型变量的区别:对信号量只能执行初始化、P、V三种操作
  • 整型信号量存在的问题:不满足让权等待原则

记录型信号量:

  • S.value表示某种资源数,S.L指向等待该资源的队列
  • P操作中,一定是先S.value–,之后可能需要执行block原语
  • V操作中,一定是先S.value++,之后可能需要执行weakup原语
  • 注意:要能够自己推断在什么条件下需要执行block或weakup
  • 可以用记录型信号量实现系统资源的“申请”和“释放”
  • 可以用记录型信号量实现进程互斥、进程同步
13、用信号量实现进程互斥、同步、前驱关系

实现进程互斥:

  • 分析问题,确定临界区
  • 设置互斥信号量,初值为1
  • 临界区之前对信号量执行P操作
  • 临界区之后对信号量执行V操作

实现进程同步:

  • 分析问题,找出哪里需要实现“一前一后”的同步关系
  • 设置同步信号量,初始值为0
  • 在“前操作”之后执行V操作
  • 在“后操作之前执行P操作”

实现进程的前驱关系:

  • 分析问题,画出前驱图,把每一对前驱关系都看成一个同步问题
  • 为每一对前驱关系设置同步信号量,初值为0
  • 在每个“前操作”之后执行V操作
  • 在每个“后操作”之前执行P操作
14、管程

为什么要引入管程:
答:解决信号量机制编程麻烦、容易出错的问题
组成:

  • 共享数据结构
  • 对数据结构初始化的语句
  • 一组用来访问数据结构的过程(函数)

基本特征:

  • 各外部进程或者线程只能通过管程提供的特定“入口”才能访问共享数据
  • 每次仅允许一个进程在管程内执行某个内部过程

补充:

  • 各进程必须互斥访问管程的特性是由编译器实现的
  • 可在管程中设置条件变量及等待/唤醒操作以解决同步问题
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值