计算机操作系统-进程的描述与控制

学习总结目录:

前趋图与程序执行

1.1 前趋图
前趋图( Precedence Graph),是指一个有向无循环图,可记为DAG( Directed Acyclic Graph),它用于描述进程之间执行的先后顺序。图中的每个结点可用来表示一个进程或程序段,乃至一条语句,结点间的有向边则表示两个结点之间存在的偏序( Partial Order)或前趋关系( Precedence Relation):

在这里插入图片描述
表示关系:
在这里插入图片描述

1.2 程序顺序执行
一个程序由若干个程序段执行,每个程序段完成特定的功能,在执行过程中,这些程序段需要按照某种顺序执行,当一个程序段完成后,才能运行后一段程序段。

例如在进行运算时,应该先运行输入程序,在运行计算程序,最后打印程序。
在这里插入图片描述
程序顺序执行的特征:

  • 顺序性: 严格按照程序规定的顺序执行
  • 封闭性: 程序运行时独占全机资源
  • 可再现性: 当环境与初始条件一样时,执行的结果也一样

1.3 程序并发执行

虽然程序顺序执行时,可以给程序员带来方便但是系统资源的利用率却很低。为此,在系统中引入了多道程序技术,使程序或程序段之间能并发执行。
在这里插入图片描述

程序并发执行时的特征:
在引入了程序间的并发执行功能后,虽然提高了系统的吞吐量和资源利用率,但由于它们共享系统资源,以及它们为完成同一项任务而相互合作,致使在这些并发执行的程序之间必将形成相互制约的关系,由此会给程序并发执行带来新的特征。

  • 间断性
  • 失去封闭性
  • 不可再现性

进程的描述

2.1 进程的定义和特征

1. 进程的定义
在多道程序环境下,程序的执行属于并发执行,此时它们将失去其封闭性,并具有间断性,以及其运行结果不可再现性的特征。为了能使程序并发执行,并且可以对并发执行的程序加以描述和控制,人们引入了“进程”的概念。

为了使参与并发执行的每个程序都独立地运行,在操作系统中必须为之配置一个专门的数据结构,称为进程控制块(Process Control Block,PCB)。系统利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。

进程实体由程序段、相关的数据段和PCB三部分组成,而所谓创建进程,实质上是创建进程实体中的PCB;而撤销进程就是撤销进程的PCB。

对于进程的定义,从不同的角度可以有不同的定义,其中较典型的定义有:

  • (1)进程是程序的一次执行。
  • (2)进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
  • (3)进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。

在引入进程实体的概念后,我们可以把传统OS中的进程定义为:“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位”

2. 进程的特征

进程和程序是两个截然不同的概念,除了进程具有程序所没有的PCB结构外,还具有下面一些特征:

  • 动态性
  • 并发性
  • 独立性
  • 异步性

2.2 进程的状态及转换

1. 进程的三种基本状态

  • 就绪(Ready)状态: 进程处于准备好运行的状态,一旦得到CPU就可以立即运行
  • 执行(Running)状态: 正在运行的进程所处的状态
  • 阻塞(Block)状态: 由于某些因素,导致该进程即使的到CPU也无法运行(还需要I/O设备),就会进入阻塞状态

2. 三种基本状态的转换

进程在运行过程中会经常发生状态的转换。正在执行的进程如果因分配给它的时间片已完而被剥夺处理机暂停执行时,其状态便由执行转为就绪;如果因发生某事件,致使当前进程的执行受阻(例如进程访问某临界资源,而该资源正被其它进程访问时),使之无法继续执行,则该进程状态将由执行转变为阻塞。

在这里插入图片描述
创建状态:进程是需要创建的,且创建进程的过程十分复杂
终止状态:分为两个步骤(首先,等待操作系统进行善后处理,然后将其PCB清零,将PCB空间返还系统)

在这里插入图片描述

3. 挂起操作:挂起处于静止,不再参与CPU的竞争

  • 终端用户的需要
  • 父进程的请求
  • 负荷调节的需要
  • 操作系统的需要

4. 进程控制块PCB(Process Control Block)

PCB是操作系统中最重要的记录型数据结构,它的作用是使一个多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。

  • 作为独立运行基本单位的标志:当系统创建一个新进程时,就会建立一个PCB,进程结束时随之消亡
  • 能实现断性运行方式
  • 提供进程管理所需的信息
  • 提供进程调度所需要的信息:如果在优先级调度算法中,需要直到进程的优先级
  • 实现与其他进程的同步与通信

进程控制块中的信息:

  • 进程标识符(PLD):外部标识符、内部标识符
  • 处理机状态
  • 进程调度信息
  • 进程控制信息

进程控制块的组织方式:

  • 线性方式(实现简单)
  • 链式方式,把具有相同状态进程的PCB分别通过PCB中的链接字链接成一个队列
  • 索引方式,系统根据所有进程状态的不同,建立几张索引表

进程控制

进程控制是进程管理中最基本的功能,主要包括创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、负责进程运行中的状态转换等功能。进程控制一般是由操作系统的内核中的原语来实现的。

3.1 操作系统内核

通常将一些硬件紧密相关的模块(如中断处理程序等)、各种常用设备的驱动程序以及运行频率较高的模块,都安排在仅靠硬件的软件层次中,将它们常驻内存,及通常被称为的OS内核。这种安排方式的目的包括:

  • 便于对这些软件进行保护
  • 提高OS的运行效率

为防止OS本身及关键数据遭受应用程序有意或无意的破坏,通常也将处理机的执行状态分为系统态和用户态:

  • 系统态(管态、内核态)具有较高特权,能执行一切指令,访问所有寄存器和存储区
  • 用户态(目态)特权较低,只能执行规定的指令,访问指定的寄存器和存储区

一般情况下,应用程序只能在用户态运行(在用户态执行的是命令解释程序)

用户状态切换到内核的3种方式:系统调用、异常、外围设备中断

支撑功能:

  • 中断处理,内核最基本的功能
  • 时钟管理,内核的一项基本功能,在时间片转轮调度、实时系统中的截止时间控制、批处理系统中的醉成运行时间控制等都需要时钟管理功能
  • 原语操作,原子操作在系统态下执行常驻内存

原语是一个程序,是不能被打断的,内核是通过各种原语操作来实现管理和控制功能的。
几个原语:
创建——终止(撤销),挂起——激活,阻塞——唤醒。P操作——V操作。
通信原语:send(发送)-receive(接收)

资源管理功能:

  • 进程管理
  • 存储器管理
  • 设备管理

3.2 进程的创建

在操作系统中,允许一个进程创建另一个进程,通常把创建进程的进程称为父进程,而被创建的进程称为子进程,子进程可以继承父进程所拥有的资源。在撤销父进程时必须撤销子进程。
在这里插入图片描述
引起创建进程的事件:

  • 用户登录
  • 作业调度
  • 提供服务
  • 应用请求

进程的创建(Creation of Process):
(1)申请空白PCB,为新进程申请获得唯一的数字标识符
(2)为新进程分配器运行所需的资源
(3)初始化进程控制块(PCB)
(4)如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列

3.3 进程的终止

引起进程终止的事件:

  • 正常结束
  • 异常结束:越界错、保护错、非法指令、特权指令错、运行超时、等待超时、算术运算错、I/O故障
  • 外界干预

3.4 进程的阻塞与唤醒

引起进程阻塞或唤醒的事件:

  • 向系统请求共享资源失败
  • 等待某种操作的完成
  • 新数据尚未到达
  • 等待新任务的到达

进程阻塞是进程自身的一种主动行为

进程的挂起:进程静止不动的状态
原因:运行空间不足,内存不足

进程同步

为了保证多个进程能够有条不紊地运行,在多道程序系统中,必须引入进程同步机制(硬件同步机制、信号量机制、管城机制)利用它们来保证程序执行的可再现性。

4.1 进程同步的基本概念

两种制约关系

  • 间接相互制约关系(互斥):系统资源竞争,进程间彼此无关
  • 直接相互制约关系(同步):进程间合作,彼此相关,有先后顺序

临界资源( Critical Resouce): 许多硬件资源如打印机、磁带机等,都属于临界资源,诸进程间应采取互斥方式,实现对这种资源的共享。(一次只能访问一个)

临界区( critical section): 不论是硬件临界资源还是软件临界资源多个进程必须互斥地对它进行访问。人们把在每个进程中访问临界资源的那段代码称为临界区( critical section)

为实现进程互斥地进入自己的临界区,可用软件方法,更多的是在系统中设置专门的同步机构来协调各进程间的运行。所有同步机制都应遵循下述四条准则:

  • 空闲让进
  • 忙则等待
  • 有限等待
  • 让权等待

4.2 硬件同步机制

虽然可以利用软件方法解决诸进程互斥进入临界区的问题,但有一定难度,并且存在很大的局限性,因而现在已很少采用。相应地,目前许多计算机已提供了一些特殊的硬件指令,允许对一个字中的内容进行检测和修正,或者是对两个字的内容进行交换等。可利用这些特殊的指令来解决临界区问题。

4.3 信号量机制(用来表示资源的数量)

1.整型信号量

最初由 Dijkstra把整型信号量定义为一个用于表示资源数目的整型量S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作( Atomic Operation) wait(S)和signal(s) 来访问。很长时间以来,这两个操作一直被分别称为P、V操作。

//P(S)<=>wait(S) V(S)<=>signal(S)
//P减一操作:S>=0系统有资源,进程执行,S<0进程进入阻塞状态
//V加一操作:S>0进程执行,S<=0系统中有等待使用资源的进程,唤醒等待的进程
wait(S){
	while(S<=0);
	S--;
}

signal(S){
	S++;
}

2. 记录型信号量

3. AND型信号量

4. 信号量集

4.4 信号量级的应用
为使多个进程能互斥地访问某临界资源,只需为该资源设置一互斥信号量 mutex,并设其初始值为1,然后将各进程访问该资源的临界区CS置于wait( mutex)和 signal( mutex)操作之间即可。

在这里插入图片描述
代码框架:

p1(){ S1; signal(a); signal(b); }
p2(){ wait(a); S2; signal(c); signal(d); }
p3(){ wait(b); S3; signal(e); }
p4(){ wait(c); S4; signal(f); }
p5(){ wait(d); S5; signal(g); }
p6(){ wait(e); wait(f); wait(g); S6; }

main(){
	semaphore a,b,c,d,e,f,g;
	a.value=b.value=c.value=d.value=e.value=f.value=g.value=0;
	cobegin
	  p1();p2();p3();p4();p5();p6();
	coend
}

进程通信

所谓进程通信是指进程之间信息交换。由于进程的互斥和同步,需要在进程间交换一定的信息,故不少学者将它们也归为进程通信,但只能被称为低级进程通信(效率低、通信对用户不透明)

高级通信:用户可直接利用OS提供的一组通信命令高效传送大量数据。可以分为四大类:

  • 共享存储器系统(Shared-Memory System) : 进程间通过共享某些数据结构或共享存储区进行通信。

  • 管道(Pipe)通信: 用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件(pipe文件)。管道机制必须提供的协调能力:互斥、同步、确定对方是否存在。

  • 消息传递系统 (Message Passing System): 进程不必借助任何共享区或数据结构,而是以格式化的消息(message)为单位,将通信的数据封装在消息中,完成进程间的数据交换。因实现方式不同可以分为两类:
    直接通信: 发送进程直接把消息发送给接收者,并将它挂在接收进程的消息缓冲队列上。接收进程从消息缓冲队列中取得消息。也称为消息缓冲通信
    间接通信: 发送进程将消息发送到某种中间实体中(信箱),接收进程从(信箱)中取得消息。也称信箱通信。在网络中称为电子邮件系统。

  • 客户机-服务器系统(Client-Server system)

线程(Threads)的基本概念

在操作系统中引入进程的目的是为了使多个程序能够并发执行,以提高资源的利用率和系统的吞吐量,那么,在操作系统中在引入线程,则是为了减少程序在并发执行时所付出的时空开销,使操作系统具有更好的并发性

进程的两个基本属性:

  • 进程是一个可拥有资源的独立单位,一个进程要能独立运行,它必须拥有一定的资源,包括用于存放程序正文数据的磁盘和内存地址空间,以及它在运行时所需要的IO设备、已打开的文件、信号量等
  • 进程同时又是一个可独立调度和分派的基本单位,一个进程要能独立运行,它还必须是一个可独立调度和分派的基本单位。

线程作为调度和分派的基本单位:
设法将进程的上述两个属性分开,由操作系统分开处理,亦即并不把作为调度和分派的基本单位也同时作为拥有资源的单位。以线程作为调度和分派的基本单位,可以有效地改善多处理机系统的性能。一些主要的OS(UNIX,Windows)厂家有进一步对线程技术做了开发,使之适用于SMP的计算机系统。

线程与进程的比较

由于线程具有传统进程所具有的特征,所以又称之为轻型进程(Light-Weigth Process)或进程元,相应地,把传统进程称之为重型进程(Heavy-Weight Process)。

  • 1.调度的基本单位
  • 2.并发性:都可以并发执行
  • 3.拥有资源:进程可以拥有资源,并作为系统中拥有资源的一个基本单位,线程本身并不拥有系统资源,而是仅有一点必不可少的、能保证自己独立运行的资源,同时它还允许多个线程共享该进程所拥有的资源。
  • 4.独立性:每个进程都拥有一个独立的地址空间和其他资源,除了共享全局变量外,不允许其它进程访问。同一进程中的不同线程往往共享进程的内存地址空间等资源
  • 5.系统开销:在创建和撤销进程时,系统都要为之分配和回收进程控制块、分配或回收其它资源,线程的切换的代价远远低于进程。
  • 6.支持多处理机系统:可将一个进程的多个线程分配到多个处理机上
    在这里插入图片描述

线程运行的三个状态:

与传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下述三种基本状态:

  • 执行状态,表示线程已获得处理机而正在运行;
  • 就绪状态,指线程已具备了各种执行条件,只须再获得CPU便可立即执行;
  • 阻塞状态,指线程在执行中因某事件受阻而处于暂停状态,例如,当一个线程执行从键盘读入数据的系统调用时,该线程就褀阳塞

线程

内核支持线程KST(Kernel Supported Threads)
在操作系统的所有进程,无论是系统进程还是用户进程,都是在操作系统内核的支持下运行的,是与内核紧密相关的。

四个优点:

  • 在多处理器系统中,内核能够同时调度同一进程中的多个线程并行执行
  • 如果进程中的一个线程被阻塞了,内核可以调度该进程中的其它线程占有处理器运行,也可以运行其它进程中的线程
  • 内核支持线程具有很小的数据结构和堆栈,线程的切换比较快,切换开销小;
  • 内核本身也可以采用多线程技术,可以提高系统的执行速度和效率。

用户级线程ULT(User Level Threads):调度过程不需要内核支持

测试题

一、选择题

1、进程与程序的根本区别是( )。
A.静态和动态特征 B.是不是被调入到内存中
C.是不是存在三种基本状态 D.是不是占有处理机

2、操作系统是根据( )来对并发执行的进程进行控制和管理的。
A.进程放入基本状态 B.进程控制块
C.多道程序设计 D.进程的优先权

3、某进程由于需要从磁盘上读入数据而处于等待状态。当系统完成了所需的读盘操作后,此时该进程的状态将( )。
A.从就绪变为运行 B.从运行变为就绪
C.从运行变为阻塞 D.从阻塞变为就绪

4、一个进程被唤醒意味着( )。
A.该进程重新占有CPU B.进程状态变为就绪状态
C.它的优先权变为最大 D.其PCB移至就绪队列的队首

5、进程从运行态到等待态可能是( )。
A.运行进程执行了P操作 B.运行进程执行了V操作
C.进程时间片用完 D.进程被调度

6、一个进程释放了一台打印机,有可能改变( )的状态。
A.自身进程 B.输入输出进程
C.另一个等待打印机的进程 D.所有等待打印机的进程

7、可能导致进程从运行状态变为就绪状态的事件为( )。
A.等待I/O操作 B.等待的事件发生
C.进程运行结束 D.出现了比当前进程优先级高的进行

8、必然会引起进程切换的事件为( )。
A.创建一个新的进程后进入就绪状态 B.一个进程从运行状态变为就绪状态
C.一个进程从阻塞状态变为就绪状态 D.以上说法都不对

9、系统中有n(n>2)个进程,则不可能发生( )。
A.有1个运行进行和n-1个就绪进程,但没有进程处于等待状态
B.有1个运行进程和1和就绪进程,剩下n-2个进程处于等待进行
C.没有运行进程,1个就绪进程,剩下的n-1个进程处于等待状态
D.没有就绪的进程和运行的进程,全部进程处于等待状态

10、下列状态的改变可以由进程自身决定的是( )。
A.从运行到阻塞 B.从运行到就绪
C.从就绪到运行 D.从阻塞到就绪

11、用户可以通过( )创建或终止一个进程。
A.函数调用 B.指令 C.系统调用 D.命令

12、两个进程合作完成一个任务,在并发执行中,一个进程要等待其合作伙伴发来信息,或者建立某个条件后再向前执行,这种关系是进程间的( )关系。
A.同步 B.互斥 C.合作 D.竞争

13、进程间的同步和互斥,分别表示了进程间的( )。
A.独立和制约 B.协作和竞争 C.动态性和独立性 D.不同状态

14、操作系统在使用信号量解决同步和互斥问题中,若P、V操作的信号量S初始值为3,当前值为-2,则表示有( )个等待进程。

15、有3个进程共享同一个程序段,而每次只允许两个进程进入该程序段,若用P、V操作同步机制,则信号量S的取值范围是( )。

16、设某资源关联的信号量初值为3,当前值为1,若M表示资源可以的数量,N表示等待资源的进程数,则M、N分别是( )。
A.0、1 B.1、0 C.1、2 D.2、0

17、执行V操作时,当信号量的值( ),应释放一个等待该信号量的进程。
A.小于0 B.大于0 C.小于等于0 D.大于等于0

18、对两个并发进程,其互斥信号量为mutex,若mutex=0,则表明( )
A.没有进程进入临界区 B.有两个进程进入临界区
C.一个进程进入临界区但没有进程处于阻塞状态
D.一个进入临界区一个出去等待进入临界区的状态

19、信箱通信是一种( )。
A.直接通信 B.间接通信 C.低级通信 D.信号量

20、下面说法正确的是( )。
A.不论是系统支持的线程还是用户级线程,其切换都需要内核的支持
B.线程是资源分配的单位,进程是调度和分派的单位
C.不管系统中是否有线程,进程都是拥有资源的独立单位
D.在引入线程的系统中,进程仍是资源调度和分配的基本单位

21、下列选项中,会导致用户从用户态切换到内核态的操作是( )
ⅰ.整数除以零 ⅱ.sin函数调用 ⅲ.read函数调用
A. ⅰ和ⅱ B. ⅰ和ⅲ C. ⅱ和ⅲ D. ⅰ、ⅱ和ⅲ

1-5 ABDBA 6-10 CDBCA
11-13 CAB 14. 2 15. (-1,0,1,2)
16-21 BCCBCB

二、综合应用题

1、进程之间存在哪些制约关系?下列活动属于哪些制约关系?
(1)若干学生去图书馆借同一本书
(2)两队进行篮球比赛
(3)流水线生产的各道工序
(4)商品生产和消费

进程之间存在着直接制约和间接制约两种制约关系,其中直接制约(同步)是由于进程间的相互合作而引起的(生产者、消费者问题),而间接制约(互斥)则是由于进程间共享临界资源而引起的。
(1)若干学生去图书馆借同一本书
间接制约关系(互斥),因为书是临界资源,需要采用互斥的方式来实现对该资源的共享。
(2)两队进行篮球比赛
间接制约关系(互斥),因为篮球是临界资源。
(3)流水线生产的各道工序
直接制约(同步),一个工序生产后才能开始下一个工序。
(4)商品生产和消费
直接制约(同步),生产后才能消费

2、某组相互合作的进程,其前趋图如下所示,信号量a,b,c,d,e,f的初始值为0,请用P、V操作实现进程间的同步操作。
在这里插入图片描述

p1(){ P1; V(a); V(b); }
p2(){ P(a); P2; V(c); }
p3(){ P(b); P3; V(d); }
p4(){ P(c); P4; V(e); }
p5(){ P(d); P5; V(f); }
p6(){ P(e); P(f); P6; }

main(){
	semaphore a,b,c,d,e,f,g;
	a.value=b.value=c.value=d.value=e.value=f.value=g.value=0;
	cobegin
	  p1();p2();p3();p4();p5();p6();
	coend
}

3、桌子上有一只盘子,每次只能向其中放入一个水果。爸爸专门向盘子中放苹果,妈妈专门向盘子中橘子,儿子专门等吃盘子中的橘子,女儿专门等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈就可向盘子中放一个水果;仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出。请利用P、V操作来实现爸爸、妈妈、儿子、女儿之间的同步和互斥关系。

semaphore f=1,mutex=1,a=0,o=0;
processDad(){
    P(f);//先判断盘子是否有空间 ,没有的话就不能向下进行了 
    P(mutex);//判断盘子是否被占用,即是否有其他人在操作
    setApple();//放置苹果 
    V(a);//苹果加一 
    V(mutex);//释放盘子资源 
} 

processMom(){
    P(f);//先判断盘子是否有空间 ,没有的话就不能向下进行了 
    P(mutex);//判断盘子是否被占用,即是否有其他人在操作 
    setOrange();//放置橘子 
    V(o);//橘子加一 
    V(mutex);//释放盘子资源 
}

processSon(){
    P(o);//先判断盘子是否有橘子 ,没有的话就不能向下进行了 
    P(mutex);//判断盘子是否被占用,即是否有其他人在操作
    eatOrange();//拿走橘子 
    V(f);//盘子空间加一 
    V(mutex);//释放盘子资源 
} 

processDaughter(){
    P(a);//先判断盘子是否有苹果 ,没有的话就不能向下进行了 
    P(mutex);//判断盘子是否被占用,即是否有其他人在操作
    eatApple();//拿走苹果 
    V(f);//盘子空间加一 
    V(mutex);//释放盘子资源 
}

4、某博物馆最多可以容纳1000人同时参观,有一个出入口,该出入口一次仅允许一个人通过。参观者的活动描述如下:

参观者进程:
{
	进门;
	……
	参观;
	……
	出门;
}
semaphore empty=1000,mutex=1;//empty表示空闲位置的数量 
P(empty);//因为是先执行进门操作,所以需要先对容量进行判断 
P(mutex);//占用临界资源 
进门; 
V(mutex);//释放 

P(mutex);//占用 
出门; 
V(mutex);//释放 
V(empty);//空间加一 

请添加必要的信号量和P、V操作以实现上述过程中的互斥与同步。要求写出完整的过程,说明信号量的含义并赋初值。

5、有一只最多能装2只兔子的铁笼子,猎人仅能向笼子中放入兔子(每次只能放入1只),若笼子是满的,则猎人必须等待;饭店老板仅能从笼子中取兔子(每次只能取出1只),若笼子是空的则他也必须等待。假设初始时笼子是空的。使用P、V操作实现猎人和饭店老板进程之间的同步与互斥。要求写出完整的过程,并对信号量赋初值。

semaphore mutex=1,empty=2,full=0;
Hunter(){
    P(empty);//先判断是否有空间 
    P(mutex);//猎人和用户要实现对笼子的互斥访问 
    V(mutex);//释放笼子资源 
    V(full);//空间减一 
}

Boss(){
    P(full);//先判断笼子里是否有兔子 
    P(mutex);//猎人和用户要实现对笼子的互斥访问 
    V(mutex);//释放笼子资源 
    V(empty);//空间加一 
} 
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙源lll

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

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

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

打赏作者

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

抵扣说明:

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

余额充值