第4章第7节 二进制信号量(三)

Linux下从信号量看线程调度时间 前几天写了一篇文章关于Linux下进程调度时间的,本意是想测试下实时性能的,包括中断响应时间等等,这个可能需要借助于硬件发出终端来测试, 那片文章是讲的是通过发送信号给另一个进程,然后测量发送信号到进入信号处理程序之间的时间 信号只是针对进程来说的,今天讲的主要是通过信号量semaphore来测试一下线程间切换的时间 首先看下基础知识: 1. 阅读详情

目前更新到5.3节,请在http://dl.dbank.com/c02ackpwp6下载5.3节的全部文档

本节源代码请在http://dl.dbank.com/c0fp2g5z9s下载

 

图53列出了多个不同状态的任务与这些调度表之间的关系,任务1被信号量sem1阻塞,处于非永久pend态,strDelayQue结构中的strQueHead节点被挂接到delay表,strTcbQue结构中的strQueHead节点被挂接到sem1表,pstrSem指针指向sem1。任务2处于ready态,strTcbQue结构中的strQueHead节点被挂接到ready表。任务3处于非永久delay态,strDelayQue结构中的strQueHead节点被挂接到delay表。任务4被信号量sem1阻塞,处于永久pend态,strTcbQue结构中的strQueHead节点被挂接到sem1表,pstrSem指针指向sem1。任务5被信号量sem2阻塞,处于非永久pend态,strDelayQue结构中的strQueHead节点被挂接到delay表,strTcbQue结构中的strQueHead节点被挂接到sem2表,pstrSem指针指向sem2。任务6处于永久delay态,不与任何调度表有关系。

第4章第7节 <wbr>二进制信号量(三)

图 53  TCB与各种调度表的关系

以上是本节新增加的内容,本节使用了4个验证任务TEST_TestTask1~TEST_TestTask4,它们的优先级分别为6,2,4,5,还有2个信号量gstrSemSync和gstrSemMute,它们都被初始化为FIFO类型。

TEST_TestTask3和TEST_TestTask4任务在开始的前3次循环中为互斥任务,在TEST_TestTask3任务获取到gstrSemMute信号量的期间内,TEST_TestTask4任务被gstrSemMute信号量阻塞,当TEST_TestTask3任务释放gstrSemMute信号量后TEST_TestTask4任务获取到gstrSemMute信号量并开始运行,此时TEST_TestTask3任务会被gstrSemMute信号量阻塞,直到TEST_TestTask4任务再次释放gstrSemMute信号量,这两个任务如此循环3次。3次循环之后,这两个任务都被阻塞到gstrSemSync信号量,需要由TEST_TestTask1任务释放gstrSemSync信号量来触发这2个任务的运行。

TEST_TestTask1任务的前10次循环用来释放gstrSemSync信号量,触发被阻塞到这个信号量上的任务。TEST_TestTask2任务一直在获取gstrSemSync信号量,需要由TEST_TestTask1任务激活。TEST_TestTask1任务运行10次循环之后,接下来的5次循环使用MDS_SemFlush函数激活所有被阻塞到gstrSemSync信号量上的任务,5次循环之后,TEST_TestTask1任务会删除gstrSemSync信号量,另外三个任务检测到gstrSemSync信号量被删除,会退出主函数,结束任务的运行。

00021  void TEST_TestTask1(void)

00022  {

00023      U8 i;

00024  

00025      i = 0;

00026  

00027      while(1)

00028      {

00029          DEV_PutStrToMem((U8*)"\r\nTask1 is running ! Tick is: %d",

00030                          MDS_SystemTickGet());

00031  

00032          DEV_DelayMs(1500);

00033  

00034          (void)MDS_TaskDelay(200);

00035  

00036          

00037          if(i < 10)

00038          {

00039              i++;

00040  

00041              DEV_PutStrToMem((U8*)"\r\nTask1 give gstrSemSync %d! Tick is: %d",

00042                              i, MDS_SystemTickGet());

00043  

00044              

00045              (void)MDS_SemGive(&gstrSemSync);

00046          }

00047          

00048          else if(i < 15)

00049          {

00050              i++;

00051  

00052              DEV_PutStrToMem((U8*)"\r\nTask1 flush gstrSemSync %d! Tick is: %d", i,

00053                              MDS_SystemTickGet());

00054  

00055              

00056              (void)MDS_SemFlush(&gstrSemSync);

00057          }

00058          

00059          else if(15 == i)

00060          {

00061              i++;

00062  

00063              DEV_PutStrToMem((U8*)"\r\nTask1 delete gstrSemSync %d! Tick is: %d", i,

00064                              MDS_SystemTickGet());

00065  

00066              

00067              (void)MDS_SemDelete(&gstrSemSync);

00068          }

00069      }

00070  }

00077  void TEST_TestTask2(void)

00078  {

00079      U8 i;

00080  

00081      i = 0;

00082  

00083      while(1)

00084      {

00085          

00086          if(RTN_SMTKDL == MDS_SemTake(&gstrSemSync, SEMWAITFEV))

00087          {

00088              DEV_PutStrToMem((U8*)"\r\nTask2 gstrSemSync deleted! Tick is: %d",

00089                              MDS_SystemTickGet());

00090  

00091              return;

00092          }

00093          else 

00094          {

00095              i++;

00096  

00097              DEV_PutStrToMem((U8*)"\r\nTask2 take gstrSemSync %d! Tick is: %d", i,

00098                              MDS_SystemTickGet());

00099  

00100              DEV_DelayMs(100);

00101          }

00102      }

00103  }

00110  void TEST_TestTask3(void)

00111  {

00112      U8 i;

00113  

00114      i = 0;

00115  

00116      while(1)

00117      {

00118          

00119          if(i < 3)

00120          {

00121              i++;

00122  

00123              

00124              (void)MDS_SemTake(&gstrSemMute, SEMWAITFEV);

00125  

00126              DEV_PutStrToMem((U8*)"\r\nTask3 take gstrSemMute %d! Tick is: %d", i,

00127                              MDS_SystemTickGet());

00128  

00129              DEV_DelayMs(500);

00130  

00131              (void)MDS_TaskDelay(150);

00132  

00133              DEV_PutStrToMem((U8*)"\r\nTask3 give gstrSemMute %d! Tick is: %d", i,

00134                              MDS_SystemTickGet());

00135  

00136              

00137              (void)MDS_SemGive(&gstrSemMute);

00138          }

00139          else 

00140          {

00141              i++;

00142  

00143              

00144              if(RTN_SMTKDL == MDS_SemTake(&gstrSemSync, SEMWAITFEV))

00145              {

00146                  DEV_PutStrToMem((U8*)"\r\nTask3 gstrSemSync deleted! Tick is: %d",

00147                                  MDS_SystemTickGet());

00148  

00149                  return;

00150              }

00151              else 

00152              {

00153                  DEV_PutStrToMem((U8*)"\r\nTask3 take gstrSemSync %d! Tick is: %d",

00154                                  i, MDS_SystemTickGet());

00155  

00156                  DEV_DelayMs(500);

00157  

00158                  (void)MDS_TaskDelay(150);

00159              }

00160          }

00161      }

00162  }

00169  void TEST_TestTask4(void)

00170  {

00171      U8 i;

00172  

00173      i = 0;

00174  

00175      while(1)

00176      {

00177          

00178          if(i < 3)

00179          {

00180              i++;

00181  

00182              

00183              (void)MDS_SemTake(&gstrSemMute, SEMWAITFEV);

00184  

00185              DEV_PutStrToMem((U8*)"\r\nTask4 take gstrSemMute %d! Tick is: %d", i,

00186                              MDS_SystemTickGet());

00187  

00188              DEV_DelayMs(500);

00189  

00190              (void)MDS_TaskDelay(200);

00191  

00192              DEV_PutStrToMem((U8*)"\r\nTask4 give gstrSemMute %d! Tick is: %d", i,

00193                              MDS_SystemTickGet());

00194  

00195              

00196              (void)MDS_SemGive(&gstrSemMute);

00197          }

00198          else 

00199          {

00200              i++;

00201  

00202              

00203              if(RTN_SMTKDL == MDS_SemTake(&gstrSemSync, SEMWAITFEV))

00204              {

00205                  DEV_PutStrToMem((U8*)"\r\nTask4 gstrSemSync deleted! Tick is: %d",

00206                                  MDS_SystemTickGet());

00207  

00208                  return;

00209              }

00210              else 

00211              {

00212                  DEV_PutStrToMem((U8*)"\r\nTask4 take gstrSemSync %d! Tick is: %d",

00213                                  i, MDS_SystemTickGet());

00214  

00215                  DEV_DelayMs(500);

00216  

00217                  (void)MDS_TaskDelay(200);

00218              }

00219          }

00220      }

00221  }

 

按照这4个任务设定的循环时间和任务优先级,开始时应该会看到TEST_TestTask1任务触发TEST_TestTask2任务,同时TEST_TestTask3任务和TEST_TestTask4任务互斥运行。当TEST_TestTask3任务和TEST_TestTask4任务互斥运行3次之后,它们不再互斥运行,而是变为同TEST_TestTask2任务一样,需要由TEST_TestTask1任务激活,此时应该看到TEST_TestTask1任务会顺序激活其它3个任务。当TEST_TestTask1任务运行10个循环之后,会使用MDS_SemFlush函数同时激活所有其它3个任务,应该会看到这3个任务全部被激活运行。TEST_TestTask1任务执行MDS_SemFlush函数5次之后会删除同步信号量,其它3个任务会发现信号量被删除而退出任务。

本节运行结果截图如下:

第4章第7节 <wbr>二进制信号量(三)

图 54  任务获取信号量的打印信息

读者可以访问http://blog.sina.com.cn/ifreecoding网站下载视频,观看全部数据的打印过程,从打印数据可以看到实际输出结果与我们的设计是一致的。

 

使用工具软件解析本节任务切换过程的数据,结果如下图所示:

 

 第4章第7节 <wbr>二进制信号量(三)

图 55  4.7节任务切换过程图

为了对比二进制信号量FIFO和PRIO属性的区别,我们将gstrSemSync信号量由FIFO属性改为PRIO属性,重新编译运行输出结果,解析PRIO属性的输出数据,结果如图56所示:

第4章第7节 <wbr>二进制信号量(三)

图 56  信号量改为PRIO属性后的任务切换过程图

我们对比图55和图56可以发现中间部分有明显的区别,中间部分是由TEST_TestTask1任务释放信号量激活其它3个任务的过程。在图55中,TEST_TestTask1任务释放信号量之后,TEST_TestTask2、TEST_TestTask3和TEST_TestTask4任务轮流被激活,而在图56中,TEST_TestTask1任务释放信号量之后却只有TEST_TestTask2任务被激活,这是因为图55的信号量采用的是FIFO属性的,会按照信号量阻塞任务的顺序轮流激活任务,而图56的信号量采用的是PRIO属性的,会激活被信号量所阻塞任务中的优先级最高的任务,因此只有优先级最高的TEST_TestTask2任务会被激活。

通信仿真笔记——算术二进制码编码与解码 信道编码与解码函数之算术二进制编码/解码 code=arithenco(seq,counts);根据指定向量seq对应的符号序列产生二进制算术代码; counts代表信源中指定符号在数据集中出现的次数 dseq=arithdeco(code,counts,len);恢复对应len符号列 算术二进制编码概念: 二进制算术编码的编码方法跟算术编码是一样的,但是输入只有两个符号:“0”,“1”,也... 阅读详情

相关推荐

任务的同步与互斥

实验报告五:(1)编程实现哲学家就餐问题。五个哲学家坐在圆桌前,每人一碗面条,每个哲学家两侧各有一支筷子,哲学家处于吃饭和思考两种状态,哲学家吃面条要用他两侧的两只筷子。 提 示:设计5个任务:Task0 、 Task1 、Task2 、Task3 、Task4 ,其优先级关系Task0>Task1>Task2>Task3>Task4。定义 5 个信号量 Sem0、 Sem1、 Sem2、 Sem3、 Sem4,每个任务 i 均作相同的工作:申请信号量 i, (i+1) mod 5;保持信号量;释放信号量(i+1) mod 5,i (2)编程实现生产者和消费者问题。一个有限共享缓冲池,缓冲池中的每个缓冲区可以存放一个产品。生产者不断生产产品并将产品放入缓冲区中,缓冲池满则不能放。消费者进程不断从缓冲区内取出产品并消费,缓冲池空则不能拿。要求生产者和消费者可以动态的增加和减少。

第4章第7节&nbsp;二进制信号量(二)

目前更新到5.3节,请在http://dl.dbank.com/c02ackpwp6下载5.3节的全部文档 本节源代码请在http://dl.dbank.com/c0fp2g5z9s下载   释放信号量的函数MDS_SemGive的代码如下: 00143  U32 MDS_SemGive(M_SEM* pstrSem) 00144  { 00145      M_TCB* pstrTcb

ifreecoding的博客 623

【Tessent Shell Users Manual】【Ch3】Design Introspection and Editing(未完待续)

Tessent Shell 提供了一系列用于检查(examining/introspecting)和编辑design的命令。

Tranquil_ovo的博客 1731

linux 信号量表,linux 内核线程,信号量,链表实现算法

下面是一个内核模块多线程的例子,不过这个模块执行的时候你卸载不了#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include#define DEBUG#if...

weixin_33791488的博客 198

VFIO框架源码分析(一)- 从初始化到设备访问

本文深入剖析了Linux内核中的VFIO(Virtual Function I/O)框架,详细解读了其从初始化到设备访问的全过程。VFIO通过Container->Group->Device的层次化设计,利用IOMMU提供安全隔离,允许用户空间直接访问物理设备。文章基于Linux v5.15版本,重点分析了vfio_init模块入口、Container创建与配置、Group关联以及最终设备访问等关键环节,揭示了VFIO如何通过逐层授权机制构建安全可靠的设备直通模型,为虚拟化技术提供核心支持。

qq_36071928的博客 380

对Palantir的本体论的理解

本体论Ontology是Palantir的整个技术架构的核心与基石,它远不止是一个数据模型,而是一个旨在对企业决策本身进行建模的“数字世界的操作系统”。

liuyukuan的专栏 1149

互斥和二进制信号量的使用

1. 二进制信号量 semBCreate (SEM_Q_FIFO/SEM_Q_PRIORITY , SEM_EMPTY/SEM_FULL) 有两个作用: (1)任务间的互斥 -- 同一个任务获取和释放信号量,防止两个任务同时存取一个资源 (2)任务间的同步 -- 一个任务获取信号量,另一个任务(或者中断)释放信号量 2. 互斥信号量 semMCreate(SEM_Q_PRIOR

greston的专栏 7146

NSGA(非支配排序遗传算法)

在多目标优化问题中,往往存在多个相互冲突的目标需要同时优化。传统的单目标优化算法无法直接应用于这类问题,因此需要专门的多目标优化算法。非支配排序遗传算法(Non-dominated Sorting Genetic Algorithm,NSGA)是一种经典的多目标优化算法,由印度科学家 Kalyanmoy Deb 等人于 1995 年提出。NSGA 通过非支配排序和拥挤度距离来引导种群向 Pareto 最优前沿进化,从而得到一组具有良好分布性和收敛性的 Pareto 最优解。

2974

第4章第7节&nbsp;二进制信号量(一)

目前更新到5.3节,请在http://dl.dbank.com/c02ackpwp6下载5.3节的全部文档 本节源代码请在http://dl.dbank.com/c0fp2g5z9s下载   第7节 二进制信号量 某些资源在同一时刻只可以被一个任务操作,实时操作系统的任务抢占特性会导致这些资源可能被多个任务同时操作,从而产生错误。本节将讲述二进制信号量的原理,可以利用二进制信号量保护这些资源

ifreecoding的博客 2039

2025美赛E题为农业留出空间(附代码+全保姆教程)Making Room for Agriculture

有机农业的核心在于减少化学投入,促进自然控制和可持续性。变量定义CCC: 作物种群III: 害虫种群PPP: 天然捕食者种群(蝙蝠、鸟类等)BBB: 生物多样性水平(以种类数量表示)SSS: 土壤健康指数(影响植物繁殖与作物生长)EEE: 农业生态系统的整体稳定性。

博客 1495

AD-Copilot 论文解读:把“大模型看图”升级为“对照检验”的工业异常检测助手

本文提出AD-Copilot,一个面向工业异常检测的视觉语言助手,通过视觉上下文比较解决现有方法的不足。针对工业场景中多模态大模型表现不佳的问题,作者指出核心原因在于缺乏工业数据和比较能力不足。为此,论文提出三个关键贡献:构建Chat-AD数据集,设计Comparison Encoder显式建模图像差异,以及采用多阶段训练策略。实验表明,该方法在MMAD基准上达到82.29%准确率,定位任务提升3.35倍,并展现出良好的泛化能力。消融实验验证了比较模块的有效性,表明其成功源于高质量比较数据与显式比较模块的协

blanokvaffy的博客 332

linux&nbsp;多线程编程&nbsp;----&nbsp;信号量的使…

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 转自:<a rel="nofollow" href= "http://blog.chinaunix.net/u3/95743/s

moonboat0331的专栏 436

从菜鸟到大神:VSCode助力HTML开发全攻略

本文全面介绍 VSCode 在 HTML 开发中的高效应用。先引导读者完成 VSCode 的安装与个性化设置,助其快速适应开发环境;接着推荐 Live Server、Prettier 等实用插件,实现实时预览、代码格式化等功能,提升开发效率。通过详细的开发实战步骤,从新建文件到添加样式,带领读者掌握 HTML 基础结构与常用标签使用。还分享代码片段管理、多人协作等进阶技巧,解决常见开发问题。旨在帮助开发者利用 VSCode,轻松高效完成 HTML 开发,打造优质网页。

邓邓子的博客 3365

信号四要素

与变量三要素(类型、名字、值)类似的,每个信号也有其必备4要素,分别是:1.编号;2.名称(即编号的宏定义) ;3.事件(引起信号产生的事件,如段错误);4.默认处理动作 可以通过man 7 signal 命令查看: Signal Value Action Comment ────────────────────────────────── SIGALRM ...

luciusvorenus 873

ZYNQ PS-PL数据交互方式总结

一,中断 二,IO方式:MIO EMIO GPIO 三,BRAM或FIFO或EMIF (1)通过BRAM实现PL/PS之间交互 PS 的配置如下图所示。使能 M_AXI_GP0 口,将 FCLK_CLK0 设为 100MHz,使能 PL 至 PS 的中断。 AXI BRAM Controller IP 核连接 PS 的 M_AXI_GP0 口和 BRAM,完成 AXI 接口至 BRAM 接口的转换。 添加BRAM,将BRAM设置为双口RAM,将PORTA与AXI B...

wangjie36的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

cmi编码实验_实验二 - 光纤通信系统线路码型CMI - 编译码实验 - 图文 -

实验二 光纤通信系统线路码型CMI 编译码实验一、实验目的1、了解线路码型在光纤传输系统中的作用2、掌握线路码型CMI码的编译码过程以及电路实现原理二、实验内容1、验证符合光纤传输系统的线路码型 2、观察线路码型的编译码过程三、实验仪器1、ZY12OFCom23BH1型光纤通信原理实验箱 2、20MHz双踪模拟示波器 3、FC-FC单模光跳线 4、连接导线1台 1台...

weixin_39707612的博客 5406

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《通信原理》复习笔记7----第七章二进制数字调制相关例题(重点)

文章目录第一题第二题第三题第四题第五题第六题第七题第八题第九题 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 第九题

遗忘丶的博客 2350

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

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

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

信号量的基本概念总结

以下内容是摘抄博客:https://blog.youkuaiyun.com/fern_girl/article/details/61197995 信号量的基本概念: 一、首先:我们要知道信号量是什么? 信号量的本质是数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能。 这是书本上介绍的信号量的概念,自己的理解比较简单: 信号量就是具有原子性的计数器,就相当于一...

Littlehero_121的博客 8272

计算机组成原理二进制地址码,计算机组成原理第四章第三讲.ppt

计算机组成原理第四章第三讲第四章 存储器;存储器概述分类层次结构主存储器概述半导体存储芯片静态随机存储器动态随机存储器只读存储器存储器与CPU的连接存储器的校验提高访存速度的措施; 高位字节 地址为字地址;CPU与存储芯片连接设计4步骤根据十六进制地址范围写出二进制地址码,并确定其容量;根据地址范围以及该范围在计算机系统中的作用确定芯片的数量及类型;分配CPU地址线(CPU低位与存储芯...

weixin_36012152的博客 1603

数字带通传输系统——二进制数字调制

引言 数字信号的传输方式分为基带传输(baseband transmission)和带通传输(bandpass transmission)。上一篇博客数字基带传输系统——数字基带信号 简单的了解了基带传输。然而,实际中的大多数信道(如无线信道)因具有带通德行而不能直接传送基带信号,这是因为数字基带信号往往具有丰富的低频分量。为了使数字信号在带通信道中传输,必须用数字基带信号对载波进行调制,以

记录一点 1万+

计算机二进制拨码,二进制拨码

科松门禁二进制拨码拨码 地码 1址 324 5 7 869 1 10 1121 31 451 6 11 17 19 80 2122 22 32 24 5262 728 293 03 132 3 34 33 53 367 8 393 0 41 44 423441 √√ √√ √ √ √ √ √√ √ √ √√ √√ √ √ √ √√√2418326√√ √ √ √√√...

weixin_34801390的博客 5505

互斥信号量和二进制信号量

互斥信号量和二进制信号量的区别(转)2009年12月03日 星期四 09:50 A.M.互斥信号量和二进制信号量的区别      互斥型信号量必须是同一个任务申请,同一个任务释放,其他任务释放无效。同一个任务可以递归申请。       二进制信号量,一个任务申请成功后,可以由另一个任务释放。二进制信号量实现任务互斥:     打印机资源只有一个,abc三个任

kaula457的专栏 1114

在Linux内核创建一个简单的testTask任务

在Linux内核创建一个简单的testTask任务,2秒输出一次打印。 #define TEST_TASK_NAME "testTask" //task name #define TASK_PRINT_STR "task test" //print int test_cnt = 0; //print counter static int test_task_thread(void *dat

donghan922的博客 1215

线程安全和多线程三要素

一、线程安全 1.什么是线程安全 线程安全就是当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。 - 通俗来讲,如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果...

bird_tp的博客 2350
上一篇: 第4章第7节&nbsp;二进制信号量(二)
下一篇: ModuleNotFoundError: No module named ‘Crypto‘
ifreecoding
博客等级 码龄15年 148粉丝 33原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值