linux修改线程优先级

Linux:线程优先级设置 同一优先级的多个线程中,一旦某个抢占式线程获取CPU,除非被更高优先级线程抢占(比如在非实时线程中创建一个更高优先级的实时线程),或该线程主动让出CPU资源,否则该线程将会一直占用CPU(但总会分配一点资源给SCHED_OTHER非实时线程)。另外,需要注意的是,只有具有足够权限的用户才能设置较高的实时线程优先级。,轮询式调度(实时线程),实时循环,设置优先级1-99,以循环方式运行,每个线程都有一个时间片来执行任务,时间片耗尽后,该线程将被放入队列的末尾,而较低优先级的线程有机会执行。 阅读详情
【转】
Linux内核的三种调度策略:

  1,SCHED_OTHER 分时调度策略,
  2,SCHED_FIFO实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃
  3,SCHED_RR实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平
 
Linux线程优先级设置
   首先,可以通过以下两个函数来获得线程可以设置的最高和最低优先级,函数中的策略即上述三种策略的宏定义:

  int sched_get_priority_max(int policy);

  int sched_get_priority_min(int policy);

  SCHED_OTHER是不支持优先级使用的,而SCHED_FIFO和SCHED_RR支持优先级的使用,他们分别为1和99,数值越大优先级越高。
设置和获取优先级通过以下两个函数

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
  int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
 param.sched_priority = 51; //设置优先级

   系统创建线程时,默认的线程是SCHED_OTHER。所以如果我们要改变线程的调度策略的话,可以通过下面的这个函数实现。

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

上面的param使用了下面的这个数据结构:

struct sched_param
{
    int __sched_priority; //所要设定的线程优先级
};

我们可以通过下面的测试程序来说明,我们自己使用的系统的支持的优先级:

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

static int get_thread_policy(pthread_attr_t *attr)
{
  int policy;
  int rs = pthread_attr_getschedpolicy(attr,&policy);
  assert(rs==0);
  switch(policy)
  {
  case SCHED_FIFO:
    printf("policy= SCHED_FIFO\n");
    break;
  case SCHED_RR:
    printf("policy= SCHED_RR");
    break;
  case SCHED_OTHER:
    printf("policy=SCHED_OTHER\n");
    break;
  default:
    printf("policy=UNKNOWN\n");
    break;
  }
  return policy;
}

static void show_thread_priority(pthread_attr_t *attr,int policy)
{
  int priority = sched_get_priority_max(policy);
  assert(priority!=-1);
  printf("max_priority=%d\n",priority);
  priority= sched_get_priority_min(policy);
  assert(priority!=-1);
  printf("min_priority=%d\n",priority);
}

static int get_thread_priority(pthread_attr_t *attr)
{
  struct sched_param param;
  int rs = pthread_attr_getschedparam(attr,&param);
  assert(rs==0);
  printf("priority=%d",param.__sched_priority);
  return param.__sched_priority;
}

static void set_thread_policy(pthread_attr_t *attr,int policy)
{
  int rs = pthread_attr_setschedpolicy(attr,policy);
  assert(rs==0);
  get_thread_policy(attr);
}

int main(void)
{
  pthread_attr_t attr;
  struct sched_param sched;
  int rs;
  rs = pthread_attr_init(&attr);
  assert(rs==0);

  int policy = get_thread_policy(&attr);
  printf("Show current configuration of priority\n");
    show_thread_priority(&attr,policy);
  printf("show SCHED_FIFO of priority\n");
 show_thread_priority(&attr,SCHED_FIFO);
  printf("show SCHED_RR of priority\n");
  show_thread_priority(&attr,SCHED_RR);
  printf("show priority of current thread\n");
  int priority = get_thread_priority(&attr);

  printf("Set thread policy\n");
  printf("set SCHED_FIFO policy\n");
  set_thread_policy(&attr,SCHED_FIFO);
  printf("set SCHED_RR policy\n");
  set_thread_policy(&attr,SCHED_RR);
  printf("Restore current policy\n");
  set_thread_policy(&attr,policy);

  rs = pthread_attr_destroy(&attr);
  assert(rs==0);
  return 0;
}

下面是测试程序的运行结果:

policy=SCHED_OTHER
Show current configuration of priority
max_priority=0
min_priority=0
show SCHED_FIFO of priority
max_priority=99
min_priority=1
show SCHED_RR of priority
max_priority=99
min_priority=1
show priority of current thread
priority=0Set thread policy
set SCHED_FIFO policy
policy= SCHED_FIFO
set SCHED_RR policy
policy= SCHED_RRRestore current policy
policy=SCHED_OTHER

 

 

这里测试一下其中的两种特性,SCHED_OTHER和SCHED_RR,还有就是优先级的问题,是不是能够保证,高优先级的线程,就可以保证先运行。
    下面的这个测试程序,创建了三个线程,默认创建的线程的调度策略是SCHED_OTHER,其余的两个线程的调度策略设置成SCHED_RR。我的Linux的内核版本是2.6.31。SCHED_RR是根据时间片来确定线程的调度。时间片用完了,不管这个线程的优先级有多高都不会在运行,而是进入就绪队列中,等待下一个时间片的到了,那这个时间片到底要持续多长时间?在《深入理解Linux内核》中的第七章进程调度中,是这样描诉的,Linux采取单凭经验的方法,即选择尽可能长、同时能保持良好相应时间的一个时间片。这里也没有给出一个具体的时间来,可能会根据不同的CPU 来定,还有就是多CPU 的情况。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void Thread1()
{
  sleep(1);
  int i,j;
  int policy;
  struct sched_param param;
  pthread_getschedparam(pthread_self(),&policy,&param);
  if(policy == SCHED_OTHER)
    printf("SCHED_OTHER\n");
  if(policy == SCHED_RR);
  printf("SCHED_RR 1 \n");
  if(policy==SCHED_FIFO)
    printf("SCHED_FIFO\n");

  for(i=1;i<10;i++)
  {
    for(j=1;j<5000000;j++)
    {
    }
    printf("thread 1\n");
  }
  printf("Pthread 1 exit\n");
}

void Thread2()
{
  sleep(1);
  int i,j,m;
  int policy;
  struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,&param);
 if(policy == SCHED_OTHER)
    printf("SCHED_OTHER\n");
  if(policy == SCHED_RR);
  printf("SCHED_RR\n");
  if(policy==SCHED_FIFO)
    printf("SCHED_FIFO\n");

  for(i=1;i<10;i++)
  {
    for(j=1;j<5000000;j++)
    {
     
    }
    printf("thread 2\n");
  }
  printf("Pthread 2 exit\n");
}

void Thread3()
{
  sleep(1);
  int i,j;
  int policy;
  struct sched_param param;
pthread_getschedparam(pthread_self(),&policy,&param);
 if(policy == SCHED_OTHER)
    printf("SCHED_OTHER\n");
  if(policy == SCHED_RR)
    printf("SCHED_RR \n");
  if(policy==SCHED_FIFO)
    printf("SCHED_FIFO\n");

  for(i=1;i<10;i++)
  {
    for(j=1;j<5000000;j++)
    {
    }
    printf("thread 3\n");
  }
  printf("Pthread 3 exit\n");
}

int main()
{
  int i;
  i = getuid();
  if(i==0)
    printf("The current user is root\n");
  else
    printf("The current user is not root\n");

  pthread_t ppid1,ppid2,ppid3;
  struct sched_param param;

  pthread_attr_t attr,attr1,attr2;
  
  pthread_attr_init(&attr1);
pthread_attr_init(&attr);
pthread_attr_init(&attr2);
 
param.sched_priority = 51;
 pthread_attr_setschedpolicy(&attr2,SCHED_RR);
 pthread_attr_setschedparam(&attr2,&param);
 pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);//要使优先级其作用必须要有这句话

 param.sched_priority = 21;
 pthread_attr_setschedpolicy(&attr1,SCHED_RR);
 pthread_attr_setschedparam(&attr1,&param);
 pthread_attr_setinheritsched(&attr1,PTHREAD_EXPLICIT_SCHED);
 
 pthread_create(&ppid3,&attr,(void *)Thread3,NULL);
 pthread_create(&ppid2,&attr1,(void *)Thread2,NULL);
 pthread_create(&ppid1,&attr2,(void *)Thread1,NULL);
 
 pthread_join(ppid3,NULL);
 pthread_join(ppid2,NULL);
 pthread_join(ppid1,NULL);
 pthread_attr_destroy(&attr2);
 pthread_attr_destroy(&attr1);
 return 0;
}

下面是该程序的其中之一的运行结果:

sudo ./prio_test
The current user is root
SCHED_OTHER
SCHED_RR
SCHED_RR 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
Pthread 1 exit
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
Pthread 2 exit
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
Pthread 3 exit

   这里我们可以看到,由于线程3的调度策略是SCHED_OTHER,而线程2的调度策略是SCHED_RR,所以,在Thread3中,线程3被线程1,线程2给抢占了。由于线程1的优先级大于线程2的优先级,所以,在线程1以先于线程2运行,不过,这里线程2有一部分代码还是先于线程1运行了。
    我原以为,只要线程的优先级高,就会一定先运行,其实,这样的理解是片面的,特别是在SMP的PC机上更会增加其不确定性。
    其实,普通进程的调度,是CPU根据进程优先级算出时间片,这样并不能一定保证高优先级的进程一定先运行,只不过和优先级低的进程相比,通常优先级较高的进程获得的CPU时间片会更长而已。其实,如果要想保证一个线程运行完在运行另一个线程的话,就要使用多线程的同步技术,信号量,条件变量等方法。而不是绝对依靠优先级的高低,来保证。
    不过,从运行的结果上,我们可以看到,调度策略为SCHED_RR的线程1,线程2确实抢占了调度策略为SCHED_OTHER的线程3。这个是可以理解的,由于SCHER_RR是实时调度策略。
   只有在下述事件之一发生时,实时进程才会被另外一个进程取代。
  (1) 进程被另外一个具有更高实时优先级的实时进程抢占。
  (2) 进程执行了阻塞操作并进入睡眠
  (3)进程停止(处于TASK_STOPPED 或TASK_TRACED状态)或被杀死。
  (4)进程通过调用系统调用sched_yield(),自愿放弃CPU 。
  (5)进程基于时间片轮转的实时进程(SCHED_RR),而且用完了它的时间片。
   基于时间片轮转的实时进程是,不是真正的改变进程的优先级,而是改变进程的基本时间片的长度。所以基于时间片轮转的进程调度,并不能保证高优先级的进程先运行。
   下面是另一种运行结果:

sudo ./prio_test
The current user is root
SCHED_OTHER
SCHED_RR 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
Pthread 1 exit
SCHED_RR
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
Pthread 2 exit
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
Pthread 3 exit

  可以看出并没有每一次都保证高优先级的线程先运行。

【Linux】实时线程的优先级设置、调度和抢占 Linux的实时线程的优先级,调度和抢占。 阅读详情

相关推荐

操作系统课设--具有优先级的线程调度

山东大学操作系统课设实验二 具有优先级的线程调度(lab2)实验目的熟悉Nachos原有的线程调度策略设计并实现具有优先级的线程调度策略修改Thread.h,修改Thread.cc修改scheduler.cc修改Test 实验二 具有优先级的线程调度(lab2) 实验目的 熟悉Nachos原有的线程调度策略 概念欠缺: .cc是方法实现,.h是头文件 步骤: 将threads里的内容copy...

qq_41545715的博客 1710

Linux-进程调度相关的系统调用简介

Linux提供了一个系统调用族,用于管理与调度程序相关的参数。这些系统调用可以用来操作和处理进程优先级、调度策略及处理器绑定。并且这些系统调用都包涵在C库中,也可用man手册查看。

一只青木呀 2283

分布式 Agent 系统设计:高并发场景下的挑战与解决方案

分布式 Agent 系统由多个分布在不同节点上的智能 Agent 组成,这些 Agent 具有自主决策能力,能够通过通信协作完成复杂任务。每个 Agent 可以看作是一个独立的实体,具备感知环境、处理信息、执行动作的功能,它们相互协作,共同实现系统的整体目标。分布式 Agent 系统在高并发场景下面临着资源调度、通信延迟、状态一致性、容错处理和性能瓶颈等诸多挑战。通过采用动态资源分配、高效通信协议、分布式共识算法、冗余备份等解决方案,可以有效应对这些挑战,提高系统的性能、可靠性和可用性。

shuizhudan223的博客 1291

Linux下线程的调度策略与优先级

Linux内核的三种调度策略:   1,SCHED_OTHER 分时调度策略, 2,SCHED_FIFO实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃    3,SCHED_RR实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平 Linux线程优先级

hexun110的专栏 1778

Vivado与Vscode无缝集成:高效Verilog开发环境搭建指南

本文详细介绍了如何将Vivado与Vscode无缝集成,打造高效的Verilog开发环境。通过替换Vivado默认编辑器为Vscode,配置必备插件和语法检查工具,开发者可以大幅提升FPGA项目的编码效率。文章还提供了代码片段、Testbench自动生成等高级技巧,帮助开发者快速上手这一集成方案。

weixin_33737774的博客 493

ESP32系列之LVGL(三):Gui-Guider的使用

Gui-Guider的使用

m0_55986987的博客 2万+

【Linux 内核】进程优先级与调度策略 ② ( 获取调度策略对应的进程优先级函数 | sched_get_priority_max 函数 | sched_get_priority_min 函数 )

一、获取进程优先级函数、 二、调度策略参数、 三、进程优先级说明、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 2691

企业微信开发007_域名主体校验未通过,需配置备案主体与当前企业主体相同或有关联关系的域名_企业内部自建应用开发_配置可信域名_回调URL_可信IP---企业微信开发009

因为我这个企业微信是,已经注册了服务商了,所以我又注册了一个不是服务商的测试企业,没有实名认证的,去试了试。而且,网络上找的教程,都是不够详细的,还是会碰到各种各样的问题,记录下来,为后来者提供便利。首先我用natapp.cn 申请了一个免费的域名,然后去,一个,企业微信上去配置,注意。我这个域名,的主体,可能是域名服务商,比如阿里域名 等等的 不是一般的企业域名。我这个企业微信,是开通了服务商的,企业微信,右上角有服务商管理后台的。到时候,直接用,他们自己企业注册的域名,已经备案的再去尝试,

添柴程序猿的专栏 1692

linux内核线程优先级设置,Linux c 线程属性,线程优先级的修改

Linux c 线程属性,线程优先级的修改发布时间:2018-07-19 10:24,浏览次数:1290, 标签:Linux线程属性的设置,网上找的文章总感觉不够全面,还是结合man手册查看。线程属性设置,分两个方式,一种是在创建之前,通过pthread_attr_t结构体传入,另一种,是线程创建完已经在运行时,通过部分函数设置。一般常见的是创建线程时传NULL,使用默认属性,后续运行时根据需要动...

weixin_39553272的博客 1007

前程无忧Python岗位数据采集:基于API直连的高效招聘信息爬取实战

本文介绍了一个基于Python requests库的前程无忧招聘数据采集系统。项目通过分析API接口结构,配置完整的请求头和身份验证参数,实现了高效稳定的数据采集。系统支持多页数据批量获取,包含工作名称、薪资范围等关键字段的结构化解析,并将结果存储为Excel文件。技术实现涉及API分析、身份验证、请求头配置、数据清洗等关键步骤,同时强调遵守法律和道德规范。该系统可为求职者、HR和市场分析师提供有价值的行业数据支持,适用于市场分析、职业规划等场景。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 1549

YOLO系列算法改进 | C3k2改进篇 | 融合DEConv细节增强卷积模块 | 细节增强+多分支差分卷积融合,标准卷积的完美涨点替代! | TIP 2024

YOLO系列算法改进 | C3k2改进篇 | 融合DEConv细节增强卷积模块 | 细节增强+多分支差分卷积融合,标准卷积的完美涨点替代! | TIP 2024 (以YOLO26最新目标检测模型为基础,融合C3k2_DEConv创新模块进行改进)

2502_91881744的博客 310

Linux c 线程属性,线程优先级的修改

线程属性的设置,网上找的文章总感觉不够全面,还是结合man手册查看。 线程属性设置,分两个方式,一种是在创建之前,通过pthread_attr_t 结构体传入,另一种,是线程创建完已经在运行时,通过部分函数设置。一般常见的是创建线程时传NULL,使用默认属性,后续运行时根据需要动态修改,也就第二种方式。 ---/--------------补充:设置优先级,除了这里所描述的sched_sets...

Canok 2万+

cuMotion 入门教程(一)面向机器人学的GPU加速运动生成技术

NVIDIA cuMotion是一款高性能机器人运动生成库,专注于机械操作任务,利用GPU加速技术提升性能。开发者预览版支持运动学/逆运动学、碰撞感知路径规划、轨迹优化等功能,兼容任意自由度机器人。该库提供C++和Python接口,支持从URDF/XRDF文件加载机器人模型,包含世界建模、碰撞检测等工具。教程详细介绍了安装配置、机器人描述加载、运动学计算、世界建模、逆运动学求解以及轨迹优化等核心功能。cuMotion整合了Lula和cuRobo库的技术优势,将成为Isaac ROS的核心组件,适用于工业机器

2506_90492529的博客 2194

linux 设置线程为idle,请问在Linux下怎么修改当前线程的优先级?

如题。|Forprocessesscheduledunderoneofthenormalschedulingpolicies(SCHED_OTHER,SCHED_IDLE,SCHED_BATCH),sched_priorityisnotusedinschedulingdecisions(itmustbespecifiedas0).Processes...

weixin_34219634的博客 336

042_小驰私房菜_MTK Camera yuv旋转90度方案

做旋转可以在app层接收到数据后,自行做旋转,也可以在hal层,针对yuv format这路流进行旋转。那我们做旋转也可以采用类似的方式。预览和录像是正常的,这个是因为预览和录像有方向相关属性可以调整,系统会根据摄像头mount的角度已经当前设备的方向,进行对应的旋转。这个下面这个文件,可以修改摄像头的mount角度。,可以看到前摄的Orientation是270,所以原始出图是做了90度的旋转。这个方案,思路就是在配流信息中,将rotation信息进行修改。注:本文章所用权归:小驰成长圈,禁止转载宣传!

587

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux进程或线程绑定到CPU+修改优先级

  转载自 https://www.cnblogs.com/swey/p/4469722.html 为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU,这样可以减少调度的开销和保护关键进程或线程。 进程绑定到CPU Linux提供一个接口,可以将进程绑定到特定的CPU: #define _GNU_SOURCE         //这行必须在下面这include之前,否则C...

chenpuo的博客 4245

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【Linux 内核】进程优先级与调度策略 ③ ( 设置、获取线程优先级的核心函数 | 修改线程调度策略函数 )

一、设置、获取线程优先级的核心函数、 二、修改线程调度策略函数

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1833

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

进程和线程(修改优先级 Windows IPC 应用移植到 Linux)

进程和线程(修改优先级 Windows IPC 应用移植到 Linux) 来源: ChinaUnix博客  日期: 2008.08.20 15:13 (共有条评论) 我要评论   当前,很多全球商务和服务都正在趋于开源 —— 业界的所有主要参与者都在争取实现此目标。这一趋势催生了一个重要的迁移模式:为不同平台(Windo

Cinberella的专栏 1487

Linux线程优先级范围

Linux定义线程优先级范围在头文件 Linux线程调度策略 Linux定义线程调度策略在头文件 SCHED_NORMAL即为SCHED_OTHER:采用分时调度策略。SCHED_FIFO:采用实时调度策略,且先到先服务,一直运行直到有更高优先级任务到达或自己放弃。SCHED_RR:采用实时调度策略,且时间片轮转,时间片用完,系统将重新分配时间片,并置于就绪队列尾。SCHED_BATCH:针对批处理进程。SCHED_IDLE:使用...

rukawashan的博客 1233

Linux线程优先级

Linux线程优先级范围 Linux定义线程优先级范围在头文件<linux/sched.h>/* *Priorityofaprocessgoesfrom0..M...

Peter的专栏 2627

关于linux下进程和线程优先级的一些总结

基础 进程优先级值越小,优先级越大,进程的优先级是PRI值不是Nice值,普通进程优先级可以通过Nice值调整,实时进程不行 Linux的进程分普通进程(非实时进程)和实时进程, 进程 调度策略 优先级 说明 普通进程 SCHED_OTHER或SCHED_NORMAL 100-139 这个区间的优先级又称为静态优先级,不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级数值越大,进程的优先级越小,分配的基时间量就越少。普通进程几乎是无法分到时间片的(只能分到5%的C

weixin_42793041的博客 5324

Linux编程-线程优先级的设定

      By:Ailson Jack       Date:2016.04.04       个人博客:www.only2fire.com       本文在我博客的地址是:http://www.only2fire.com/archives/60.html,排版更好,便于学习。       最近在学习Linux的编程,这里在博客中记录一下学习的过程。       对于线程的优先级设定...

Ailson Jack的专栏 7026

进程多线程提高优先级

Linux性能调优的时候,可能会用到renice命令提高进程优先级。我以前使用 但是后面发现对于多线程的进程,这样只能修改到进程主线程的优先级,如果需要都修改到,则需要使用GID现在使用 优先级对于线程较多的进程还是有一定的调优效果的。...

qq_19274391的博客 954

Linux修改调度策略和优先级

1. 在Linux系统中,线程和进程之于Linux系统内核调度器来说是一样的,线程会当做进程一样来参与调度,也可以说线程是内核调度的最小单元。2.子进程或子线程会继承父进程/线程的调度策略。

weixin_38331755的博客 2268
上一篇: ubuntu 16.04 make menuconfig 失败 解决方法
下一篇: QT QString 转 char* 中文乱码问题
不是很大锅
博客等级 码龄10年 34粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值