操作系统:死锁

操作系统中的CPU调度:死锁预防 如果一个进程正在持有一些资源并等待其他资源,那么它应该释放所有先前持有的资源并再次发出对所需资源的新请求。保持并等待是一种情况,其中一个进程在持有一个资源的同时等待另一个进程持有的另一种资源。如果进程 P1 正在使用资源,并且高优先级进程 P2 请求该资源,则进程 P1 会停止,并将资源分配给 P2。必要条件中的任何一个。这些方法是有问题的,因为进程可能正在积极使用这些资源,并且通过抢占来停止进程可能会导致不一致。在假脱机中,当多个进程请求打印机时,它们的作业(需要打印机访问权限的进程的指令)将被添加到。 阅读详情

死锁

什么是死锁?

在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲就是两个或多个进程无限期的阻塞、相互等待的一种状态。

死锁产生的四个必要条件

  • 互斥条件: 一个资源一次只能被一个进程使用;
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得资源保持不放;
  • 不剥夺条件: 进程获得的资源,在未完全使用完之前,不能强行剥夺;
  • 循环等待条件: 若干进程之间形成一种头尾相接的环形等待资源关系。

解决死锁的思路

  • 预防死锁: 通过破坏死锁四个必要条件之一,来防止死锁产生;
  • 避免死锁: 在资源的动态分配过程中,用某种方法防止系统进入不安全状态,从而避免发生死锁;
  • 检测死锁: 允许进程在运行过程中发生死锁,但是可以通过检测机构及时检测出死锁,然后通过合适的措施,把进程从死锁过程中解脱出来;
  • 解除死锁: 当检测系统中已经发生死锁时,就采用相应措施,将进程从死锁状态中解脱出来。
  • 忽略死锁: 比如:鸵鸟算法,当系统发生死锁时不会对用户造成多大影响,或系统很少发生死锁的场合。

静态策略:预防死锁

破坏“互斥”条件

如果把只能互斥使用的资源改造为允许共享使用,则系统不会进入死锁状态。

比如:SPOOLing技术。操作系统可以采用SPOOLing 技术把独占设备在逻辑上改造成共享设备。

在这里插入图片描述

缺点:并不是所有的资源都可以改造成可共享使用的资源。并且为了系统安全,很多地方还必须保护这种互斥性。因此,很多时候都无法破坏互斥条件。

破坏“请求和保持”条件

我们必须保证:当一个进程在请求资源时,它不能持有不可抢占的系统资源。在此,有两种协议可供选择。

第一种协议: 该协议规定,所有进程在开始运行之前,必须一次性地申请其在整个运行过程中所需的全部资源。此时若系统有足够的资源分配给某进程,便可把其需要的所有资源分配给它,这样,该进程在整个运行期间,便不会再提出资源要求,从而破坏了“请求”条件。系统在分配资源时,只要有一种资源不能满足进程的要求,即使其它所需的各资源都空闲也不分配给该进程;

第一种协议虽然简单易行且安全,但是它导致资源被严重浪费,严重的降低了资源的利用率;进程会经常发生饥饿现象。 因此比较推荐第二种协议。

第二种协议: 该协议是对第一种协议的改进,它允许一个进程只获得运行初期所需的资源后,便开始运行。进程运行过程中再逐步释放已分配给自己的、且已用毕的全部资源,然后再请求新的所需资源。

破坏“不剥夺”条件

方案一:当某个进程请求新的资源得不到满足时,便立即释放保持的所有资源,待以后需要时再重新申请。也就是说,即使某些资源尚未使用完,也需要主动释放,从而破坏了不可剥夺条件。

方案二:当某个进程需要的资源被其他进程所占有的时候,可以由操作系统协助,将想要的资源强行剥夺。这种方式一般需要考虑各进程的优先级。比如剥夺调度方式,就是将处理机资源强行剥夺给优先级更高的进程使用。

缺点:

  1. 实现起来比较复杂。
  2. 释放已获得的资源可能造成前一阶段工作的失效。因此这种方法一般只适用于易保存和恢复状态的资源,如CPU。
  3. 反复地申请和释放资源会增加系统开销,降低系统吞吐量。
  4. 若采用方案一,意味着只要暂时得不到某个资源,之前获得的那些资源就都需要放弃,以后再重新申请。如果一直发生这样的情况,就会导致进程饥饿。

破坏“循环等待”条件

顺序资源分配法: 首先给系统中的资源编号,规定每个进程必须按编号递增的顺序请求资源,同类资源(即编号相同的资源)一次性申请完。

原理: 一个进程只有已占有小编号的资源时,才有资格申请更大编号的资源。按此规则,已持有大编号资源的进程不可能逆向地回来申请小编号的资源,从而就不会产生循环等待的现象,进而预防死锁的发生。

缺点:

  1. 不方便增加新的设备,因为可能需要重新分配所有的编号;
  2. 进程实际使用资源的顺序可能和编号递增顺序不一致,会导致资源浪费;
  3. 必须按规定次序申请资源,用户编程麻烦。

动态策略:避免死锁

安全序列

所谓安全序列,就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。

如果分配了资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利的执行下去。

当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过我们在分配资源之前总是要考虑到最坏的情况。

系统的不安全状态与死锁的联系

如果系统处于安全状态,就一定不会发生死锁。

如果系统进入不安全状态,就可能发生死锁。

处于不安全状态未必就是发生了死锁,但发生死锁时一定是在不安全状态。

因此可以在资源分配之前预先判断这次分配是否会导致系统进入不安全状态,以此决定是否答应资源分配请求。

这也是“银行家算法”的核心思想。

银行家算法

核心思想:在进程提出资源申请时,先预判此次分配是否会导致系统进入不安全状态。如果会进入不安全状态,就暂时不答应这次请求,让该进程先阻塞等待。

举例,系统中有5个进程P0-P4,3种资源R0~R2,初始数量为(10,5,7),则某一时刻的情况可表示如下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

银行家算法的代码实现:

假设系统中有n个进程,m种资源。

每个进程在运行前先声明对各种资源的最大需求数,则可用一个n*m的矩阵(可用二维数组实现)表示所有进程对各种资源的最大需求数。不妨称为最大需求矩阵Max,Max[i, j]=K表示进程Pi最多需要K个资源Rj。

同理,系统可以用一个n*m的分配矩阵Allocation表示对所有进程的资源分配情况。
由此得到Max - Allocation = Need矩阵,表示各进程最多还需要多少各类资源。

另外,还要用一个长度为m的一维数组Available表示当前系统中还有多少可用资源。

某进程Pi向系统申请资源,可用一个长度为m的一维数组Request表示本次申请的各种资源量。

可用银行家算法预判本次分配是否会导致系统进入不安全状态:

  1. 如果 R e q u e s t [ i ] ≤ N e e d [ i , j ] ( 0 ≤ j ≤ m ) R e q u e s t [ i ] ≤ N e e d [ i , j ] ( 0 ≤ j ≤ m ) Request[i]≤Need[i,j](0≤j≤m) 便转向2,否则认为出错。
  2. 如果 R e q u e s t [ i ] ≤ A v a i l a b l e [ i ] ( 0 ≤ j ≤ m ) R e q u e s t [ i ] ≤ A v a i l a b l e [ i ] ( 0 ≤ j ≤ m ) Request[i]≤Available[i](0≤j≤m),便转向3,否则表示尚无足够资源,Pi必须等待。
  3. 系统试探着把资源分配给进程Pi,并修改相应的数据(并非真的分配,修改数值只是为了做预判)。
    在这里插入图片描述
  4. 操作系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式分配;否则,恢复相应数据,让进程阻塞等待。

安全性算法步骤:

  1. 检查当前的剩余可用资源是否能满足某个进程的最大需求,
  2. 如果可以,就把该进程加入安全序列,并把该进程持有的资源全部回收。
  3. 不断重复上述过程,看最终是否能让所有进程都加入安全序列。

死锁的检测与解除

预防死锁和避免死锁,都是不允许死锁的发生。而死锁的检测与解除允许死锁的发生,然后发现并解决死锁。

资源分配图

在这里插入图片描述

两种结点:

  • 进程结点:对应一个进程。

  • 资源结点:对应一类资源,一类资源可能有多个。

两种边:

  • 进程结点→资源结点:表示进程想申请几个资源(每条边代表一个)
  • 资源节点→程结点:表示已经为进程分配了几个资源(每条边代表一个)

死锁的检测

为了能对系统是否已发生了死锁进行检测,必须:

  1. 用某种数据结构(资源分配图)来保存资源的请求和分配信息。
  2. 提供一种算法,利用上述信息来检测系统是否已进入死锁状态。

死锁检测算法:

  1. 在资源分配图中,找出既不阻塞又非独立的进程结点Pi,在顺利的情况下,Pi可以得到所需的资源而继续运行,直至完成,然后释放它所占有的所有资源。这相当于消去它所有的请求边和分配边,使之称为孤立的结点。
  2. 进程Pi所释放的资源,可以唤醒某些因等待这些资源而阻塞的进程,原来的阻塞进程可能变为非阻塞进程。然后重复上面的过程,消去请求边和分配边。
  3. 若能消去图中所有的边,使得图中的进程结点变为孤立点,则称该图是可完全简化的,否则称该图是不可完全简化的。

如果某时刻系统的资源分配图是不可完全简化的,那么此时系统死锁。

举例:

在这里插入图片描述

P1既不阻塞又不是孤点,消去它所有的请求边和分配边,使之称为孤立的结点。然后唤醒被阻塞的P2,消去它所有的请求边和分配边,该图是可完全简化的。

死锁的解除

主要有3中方法:

  1. 资源剥夺法:挂起(暂时放到外存上)某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但是应防止被挂起的进程长时间得不到资源而饥饿。
  2. 撤销进程法(或称终止进程法):强制撤销部分、甚至全部死锁进程,并剥夺这些进程的资源。这种方式的优点是实现简单,但所付出的代价可能会很大。因为有些进程可能已经运行了很长时间,已经接近结束了,一旦被终止可谓功亏一篑,以后还得从头再来。
  3. 进程回退法:让一个或多个死锁进程回退到足以避免死锁的地步。这就要求系统要记录进程的历史信息,设置还原点。

解决死锁的优先级:

  1. 进程优先级
  2. 已执行多长时间
  3. 还要多久能完成
  4. 进程已经使用了多少资源
  5. 进程是交互式的还是批处理式的
计算机启动:操作系统死锁 进程 1 持有“资源 1”并需要“资源 2”,而进程 2 持有“资源 2”并需要“资源 1”。这就造成了死锁的情况,因为两个进程都无法执行。但是,如果发生死锁,我们可以重新启动系统,死锁就会自动解决。由于当上述四个条件全部满足时就会发生死锁,因此我们尽量避免其中任何一个,从而防止死锁。因此,它需要额外的信息,例如进程需要每种类型的多少资源。死锁是一种情况,其中多个进程被阻塞,因为它占用了资源,并且还需要其他进程获取某些资源。我们让系统陷入死锁,如果发生死锁,我们会使用检测算法检测到它并尝试恢复。 阅读详情

相关推荐

操作系统中有关预防死锁的问题

操作系统中有关预防死锁的问题

操作系统中不安全状态为何并非一定转为死锁?

在学习避免死锁、银行家算法时,对于安全状态一定不会产生死锁,不安全状态也并非必然转为死锁,不止你是否会疑惑为何处于不安全状态下,不是必然会发生死锁?

丹丹的后花园 3万+

操作系统死锁问题

进程死锁的检测:资源分配图的化简判断是否有死锁发生

操作系统----死锁

在银行家算法中定义了几个数组用来记录数据,max数组用来记录进程告知操作系统的最大请求的资源数,Allcation数组用来记录进程已被分配的资源数,need数组记录进程还需要的资源数,request数组记录本次进程请求的资源数,available记录操作系统还能分配的资源数。按照这种方式就无法形成资源等待环导致所有进程发生死锁,假设有两个进程都申请了一个资源,那这两个资源的编号肯定有小有大,小号资源的进程能等待大号的资源但是大号资源无法回过头等待小号资源所以避免了死锁问题。:1.实现起来比较复杂。

weixin_64208331的博客 431

PVT(Process Voltage Temperature)

芯片PVT

网始如芯个人博客 3万+

Skyworks SKY85331-11的Wi-Fi 6 (802.11ax)标准 2.4G 高功率WLAN前端模块解决方案

SKY85331-11是高度集成的2 GHz前端模块(FEM)包含2 GHz单刀双掷(SPDT)发送/接收(T / R)开关,2 GHz低噪声放大器(LNA)带旁路和一个2 GHz功率放大器(PA),用于大功率802.11ax应用程序和系统LNA和PA禁用功能可确保低漏电流 关闭模式。 包括一个集成的功率检测器以提供系统内的闭环功率控制。该设备提供Small (24-pin, 3 x 5 mm) (LGA)封装。 图1.引脚配置和封装如图所示 图2.信号引脚分配和功能引脚描述 图...

zhangbao19890622的博客 4509

浅谈死锁

上一篇聊了线程安全。 线程安全的主要解决办法是实现可重入函数。 而可重入函数中的六大特征中的第五点,则引入了线程锁的机制。 而锁的机制,则会引发死锁的风险。 是否会引发锁,这个在于锁的正确使用。 当然,还需要说明一点,并非只有线程会出现死锁,并发的进程,也会引发死锁。 当前除了线程锁,还有进程锁,还有更大规模应用场景下的分布式锁。当然本文只讲线程锁。 那么,什么情况下会引发死锁...

洛城的博客 473

如何通过CAD图中的坐标来确定是哪个坐标系

地理坐标系:为球面坐标。参考平面地是椭球面,坐标单位:经纬度。以地球参考为例,坐标系就相当于整个地球,而地理坐标系就是椭球状的完整的立体地球。所以我们可以看到生活中的数据与地图是一定含有地理坐标系的,因为他是客观上来说确确实实存在的。投影坐标系:为平面坐标。参考平面地是水平面,坐标单位:米、千米等。这就相当于把地球当成一个橘子,然后一刀切开,把橘子皮平面铺开,这个过程就是地理投影的过程。严谨一点来说就是建立一个参考系统,按照对应位置把椭球体投射到平面。那坐标系统主要有那些呢?北京54。

vjmap的博客 2万+

操作系统:死锁(死锁条件,预防死锁,避免死锁,乐/悲观锁)

①互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只供一个进程占用。如果此时其他进程请求该资源,请求者只能等待—(资源独占) ②请求和保持:指进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又已被其它进程占用,此时请求进程阻塞,但又对自己已获得的其它资源保持不放—(部分分配,占有申请) ③不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放; ④环路等待条件:指在发生死锁时,必然存在一个进程—资源的环形链,即进程集合{P0,P1,P2,…

燕双嘤 2957

「点燃我,温暖你」用Python制作一个动态爱心效果

最近「点燃我,温暖你」这部剧非常火,讲述的是程序员的爱情故事。其中陈飞宇饰演的男主李峋,在剧中用程序做出的爱心跳动效果,非常炫。

Modeler_xiaoyu的博客 1万+

STM32CubeMX-电机控制2-电机相关配置部分

STM32CubeMX-电机霍尔传感器 写在前面的话:之前一直使用库函数,调程序时总会觉得是配置出现问题,要画一些时间去检查配置程序,所以目前转到了STM32CubeMX。写这些内容一方面是整理记录,因为是刚入门,所以难免出现错误,希望能得到大家指正;另一方面是因为自己一个人调试,走了很多弯路,写下来希望能给相同处境的人一些参考。 步骤一: 电机霍尔传感器接口 我目前使用的是STM32F4,电机的...

niker_co的博客 1万+

【操作系统】二、进程管理:4.死锁(银行家算法、系统安全状态、静态分配策略、资源有序分配法)

【规范】在并发环境下(多道程序环境中),各进程因竞争有限的资源而造成的一种互相等待对方手里的资源,导致各进程都阻塞,都无法向前推进的现象,就是“死锁”。发生死锁后若无外力干涉,这些进程都将无法向前推进。。可能是只有一个进程“饥饿”。【规范】由于长期得不到想要的资源,某进程无法向前推进的现象。比如:在短进程优先(SPF)算法中,若有源源不断的短进程到来,则长进程将一直得不到处理机,从而发生长进程“饥饿”。:某进程执行过程中一直跳不出某个循环的现象。

关注:https://github.com/Suhan42 2250

Arduino-Pico:用Arduino生态开发树莓派RP2040双核与PIO实战

在嵌入式开发领域,微控制器编程是连接硬件与软件的核心技能。其原理在于通过编写代码直接控制处理器与外设,实现特定功能。掌握这项技术能极大提升开发效率,降低硬件操作门槛,广泛应用于物联网、智能硬件和自动化控制等场景。本文聚焦于如何利用Arduino这一广受欢迎的生态,来开发树莓派RP2040微控制器。RP2040以其双核Cortex-M0+架构和独特的可编程IO(PIO)硬件而著称,性能强大。通过第三方Arduino核心(arduino-pico),开发者可以沿用熟悉的Arduino语法和库,快速调用双核并行处

weixin_26905423的博客 381

操作系统:产生死锁的原因、必要条件以及解决死锁的基本办法

对产生死锁的原因、必要条件以及解决死锁的基本办法进行了相关的介绍!

坤舆湖畔的万某某的博客 1万+

深入学习FIFO

深入理解FIFO、同步FIFO和异步FIFO、FIFO设计的难点以及FIFO深度计算

好好学习,天天向上 2651

1. 在 SAP ABAP 事物码 SEGW 里创建 SAP OData 项目

本文介绍如何在 SAP ABAP 事物码 SEGW 里创建 SEGW 项目,使用工具生成 Runtime 运行时需要的资源。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5446

计算机操作系统:死锁概述

在多进程并发的操作系统中,进程之间需要共享CPU、内存、打印机、文件等各类资源。当多个进程为了争夺有限的资源,陷入“互相等待对方释放资源”的循环状态——你占着我要的资源,我占着你要的资源,谁都无法继续推进,这种“谁也动不了”的僵局就是死锁。比如:进程A持有打印机,却在等待进程B占用的扫描仪;而进程B持有扫描仪,又在等待进程A的打印机,二者永远卡在等待状态,既无法完成任务,也无法释放已占资源。死锁不是“进程崩溃”或“系统卡顿”,而是一种“逻辑上的停滞”,一旦发生,若无外力干预,死锁进程将永久阻塞。

梁辰兴的博客 1315

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

操作系统:死锁处理方法

如果不了解死锁,可以通过这篇文章进行了解:死锁的概念及资源分配图我们都知道,操作系统可能会遇到死锁这种情况,那么处理死锁的方法有哪些呢?处理死锁和我们生活中遇到的消防很“类似”。下面就是4种应付死锁的方法:死锁预防(Deadlock Prevention):确保系统永远不会进入死锁状态。举个例子,消防上为了预防火灾,如果禁止在任何时刻任何地点使用任何的火,这样就可以保证不会发生火灾了。我们都知道,...

Cookie1997的小屋 6430

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

2.1.4操作系统-进程管理:死锁、死锁的产生条件、死锁资源数计算

破坏保持和等待,B等待一会儿,没有资源,就释放调自己占用的资源🍓,这样A进程就可以拿到缺少的资源🍓,然后继续执行,A用完释放掉资源,再给B用。破坏互斥条件,资源不再是不可共享的,也就是说B的🍓可以给A用,这样A进程就可以拿到缺少的资源🍓,然后继续执行,A用完释放掉资源,再给B用。破坏不剥夺,A去抢B的🍓,抢到后,这样A进程就可以拿到缺少的资源🍓,然后继续执行,A用完释放掉资源,再给B用。假设资源是🍍🍍🍓,现在有两个进程A、B,进程A需要🍍🍍🍓,进程B需要🍍🍓,现在状态是A🍍🍍,B🍓。

郝开的博客 1351

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【操作系统-Day 27】死锁终结者:当死锁发生后,我们如何检测与解除?

在某些系统中,为了追求更高的资源利用率和系统吞吐量,我们可能允许死锁的发生,转而采用一种“亡羊补牢”的策略:死锁的检测与解除。本文将深入剖析当死锁不幸发生时,操作系统是如何扮演“侦探”和“终结者”角色的。我们将详细讲解基于资源分配图的死锁检测算法,并系统地阐述两种主流的死锁解除方法——进程终止和资源抢占,以及它们各自的优缺点与实施细节。

吴师兄大模型的博客 1189

操作系统基础:死锁

推荐关注博主!获取更多关于操作系统的最新技术分享!

m0_51574586的博客 1341

操作系统:避免死锁

操作系统:避免死锁的设计与基于C++的实现

xieeix_code的博客 851

现代操作系统:死锁

在许多应用中,需要一个进程排他性地访问若干种资源而不是一种。当两个(或更多)进程各自独占某一资源而同时被阻塞,并且一直处于这样的状态。这种状况就叫死锁。 除了请求独占性的I/O设备外,软件资源(如数据库)也会可能出现死锁。资源大部分死锁都和资源有关,资源可以是硬件设备或是一组信息(如数据库中的一个加锁的记录)。简单来说,资源就是随着时间的推移,必须能获得、使用以及释放的任何东西。

jinzhao1993的博客 1049

计算机操作系统:预防死锁

预防死锁的核心是“提前干预,从根源杜绝”,其本质是通过规则破坏死锁的四个必要条件之一,核心结论可归纳为:🛡️策略逻辑:互斥条件可通过共享队列/资源池破坏,但仅适用于可共享资源;持有并等待条件可通过“一次性申请”或“释放再申请”破坏,安全但灵活度低;不可剥夺条件可通过超时或优先级剥夺破坏,适合实时系统但需避免数据不一致;循环等待条件可通过资源有序分配破坏,是平衡利用率与灵活性的最优选择。🎯选型关键:实时系统优先选“优先级剥夺”(保障紧急任务);批处理系统可选“一次性申请”(逻辑简单);

梁辰兴的博客 1075

操作系统:对于死锁的理解

死锁是并发编程中多个线程互相持有对方所需资源而无法继续执行的现象。产生死锁需满足四个条件:互斥、请求与保持、不可剥夺和循环等待。解决死锁的两种主要方法是银行家算法和按序加锁。银行家算法通过预分配资源和检查安全序列来避免死锁,但实现复杂;按序加锁则通过统一加锁顺序破坏循环等待,实现简单高效,成为工业界首选方案。实际开发中按序加锁的落地性更强,而银行家算法多用于理论场景。

2301_80191696的博客 376
上一篇: 我的第一个 VTK 程序
下一篇: 进程、线程、协程
UestcXiye
博客等级 码龄8年 9031粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值