2.9 Centos7系统进程管理

系统进程管理

本章所讲内容:
1)进程概述和ps查看进程工具
2)uptime查看系统负载–top动态管理进程
3)前后台切换-nice进程优先级-实战screen后台执行命令

1、进程概述和PS管理进程

1)什么是进程

进程是已启动的可执行程序的运行实例,进程有以下组成部分:
• 已分配内存的地址空间;
• 安全属性,包括所有权凭据和特权;
• 程序代码的一个或多个执行线程;
• 进程状态
程序: 二进制文件,静态 /bin/date,/usr/sbin/sshd
进程: 是程序运行的过程, 动态,有生命周期及运行状态

下图所示是进程的生命周期:
在这里插入图片描述
描述如下:
父进程复制自己的地址空间(fork [fɔ:k] 分叉)创建一个新的(子)进程结构。每个新进程分配一个唯一的进程 ID (PID),满足跟踪安全性之需。PID 和 父进程 ID (PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程的后代。
centos5或6PID为1的进程是: init
centos7 PID为1的进程是: systemd
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
用自己的话表达:父进程退出了, 子进程没有退出, 那么这些子进程就没有父进程来管理了,就变成僵尸进程。

2)进程的属性

进程ID(PID):是唯一的数值,用来区分进程
父进程的ID(PPID)
启动进程的用户ID(UID)和所归属的组(GID)
进程状态:状态分为运行R、休眠S、僵尸Z
进程执行的优先级
进程所连接的终端名
进程资源占用:比如占用资源大小(内存、CPU占用量)

3)使用ps查看进程工具

例1:常用的参数:
a:显示跟当前终端关联的所有进程
u:基于用户的格式显示(U:显示某用户ID的所有进程)
x:显示所有进程,不以终端机来区分
例2:常用的选项组合是 ps -axu
在这里插入图片描述
【注】
最后一列[xxxx] 使用方括号括起来的进程是内核态的进程。 没有括起来的是用户态进程。
上面的参数输出每列含意:
USER: 启动这些进程的用户
PID: 进程的ID
%CPU 进程占用的CPU百分比;
%MEM 占用内存的百分比;
VSZ:进程占用的虚拟内存大小(单位:KB)
RSS:进程占用的物理内存大小(单位:KB)
STAT:该程序目前的状态;
Linux进程有5种基本状态:
R :该程序目前正在运作,或者是可被运作;
S :该程序目前正在睡眠当中 (可说是 idle 状态啦!),但可被某些讯号(signal) 唤醒。
T :该程序目前正在侦测或者是停止了;
Z :该程序应该已经终止,但是其父程序却无法正常的终止他,造成 zombie (疆尸) 程序的状态
D 不可中断状态.
5个基本状态后,还可以加一些字母,比如:Ss、R+,如下图:
在这里插入图片描述
它们含意如下:
<: 表示进程运行在高优先级上
N: 表示进程运行在低优先级上
L: 表示进程有页面锁定在内存中
s: 表示进程是控制进程
l: 表示进程是多线程的
+: 表示当前进程运行在前台
START:该 process 被触发启动的时间;
TIME :该 process 实际使用 CPU 运作的时间。
COMMAND:该程序的实际指令

例1:查看进程状态

先打开一个终端

[root@CHENDAJIE ~]# vim a.txt

在另一个终端中执行:

[root@CHENDAJIE ~]# ps -aux | grep a.txt	#查看状态 S表示睡眠状态, + 表示前台
root       9973  0.1  0.2 151764  5292 pts/0    S+   10:10   0:00 vim a.txt
root       9979  0.0  0.0 112676   992 pts/9    S+   10:11   0:00 grep --color=auto a.txt

在vim a.txt这个终端上 按下 ctrl+z

[1]+  已停止               vim a.txt

在另一个终端执行:

[root@CHENDAJIE ~]# ps -aux | grep a.txt	#查看状态T表示停止状态
root       9973  0.0  0.2 151764  5292 pts/0    T    10:10   0:00 vim a.txt
root      10042  0.0  0.0 112676   996 pts/9    S+   10:17   0:00 grep --color=auto a.txt

【注】
ctrl-c 是发送 SIGINT 信号,终止一个进程
ctrl-z 是发送 SIGSTOP信号,挂起一个进程。将作业放置到后台(暂停)
ctrl-d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF。代表输入完成或者注销

例2: D 不可中断状态

先在一个进程中执行以下命令:

[root@CHENDAJIE ~]# tar -zcvf usr-tar.gz /usr/

然后在另一个终端不断查看状态,由S+, R+变为D+

[root@CHENDAJIE ~]# ps -aux | grep tar
chendaj+   6525  0.0  0.2 1279104 5108 ?        S<l  07:46   0:00 /usr/bin/pulseaudio --start --log-target=syslog
root      10136 11.5  0.0 123660  1480 pts/0    S+   10:25   0:00 tar -zcvf usr-tar.gz /usr/
root      10139  0.0  0.0 112680   980 pts/9    S+   10:25   0:00 grep --color=auto tar
[root@CHENDAJIE ~]# ps -aux | grep tar
chendaj+   6525  0.0  0.2 1279104 4704 ?        S<l  07:46   0:00 /usr/bin/pulseaudio --start --log-target=syslog
root      10136 10.5  0.0 123660  1484 pts/0    R+   10:25   0:01 tar -zcvf usr-tar.gz /usr/
root      10155  0.0  0.0 112680   980 pts/9    S+   10:25   0:00 grep --color=auto tar
[root@CHENDAJIE ~]# ps -aux | grep tar
chendaj+   6525  0.0  0.2 1279104 4704 ?        S<l  07:46   0:00 /usr/bin/pulseaudio --start --log-target=syslog
root      10136 10.6  0.0 123660  1484 pts/0    D+   10:25   0:01 tar -zcvf usr-tar.gz /usr/
root      10159  0.0  0.0 112680   984 pts/9    S+   10:25   0:00 grep --color=auto tar

2、ps常用的参数:ps -ef

-e:显示所有进程
-f:显示完整格式输出
常用组合:ps -ef

[root@CHENDAJIE ~]# ps -ef | head
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 01:06 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
root          2      0  0 01:06 ?        00:00:00 [kthreadd]
root          3      2  0 01:06 ?        00:00:00 [ksoftirqd/0]
root          5      2  0 01:06 ?        00:00:00 [kworker/0:0H]
root          7      2  0 01:06 ?        00:00:00 [migration/0]
root          8      2  0 01:06 ?        00:00:00 [rcu_bh]
root          9      2  0 01:06 ?        00:00:07 [rcu_sched]
root         10      2  0 01:06 ?        00:00:01 [watchdog/0]
root         11      2  0 01:06 ?        00:00:00 [watchdog/1]

包含的信息如下
UID: 启动这些进程的用户
PID: 进程的ID
PPID: 父进程的进程号
C: 进程生命周期中的CPU利用率
STIME: 进程启动时的系统时间
TTY: 表明进程在哪个终端设备上运行。如果显示 ?表示与终端无关,这种进程一般是内核态进程。另外, tty1-tty6 是本机上面的登入者程序,若为 pts/0 等,则表示运行在虚拟终端上的进程。
TIME: 运行进程一共累计占用的CPU时间
CMD: 启动的程序名称

例1:测试CPU使用时间
[root@CHENDAJIE ~]# dd if=/dev/zero of=/a.txt count bs=100M
[root@CHENDAJIE ~]# ps -aux | grep dd
root          2  0.0  0.0      0     0 ?        S    01:06   0:00 [kthreadd]
root         59  0.0  0.0      0     0 ?        S<   01:06   0:00 [ipv6_addrconf]
root        704  0.0  0.2 216980  4232 ?        Ss   01:06   0:00 /usr/bin/abrt-watch-log -F BUG: WARNING: at WARNING: CPU: INFO: possible recursive locking detected ernel BUG at list_del corruption list_add corruption do_IRQ: stack overflow: ear stack overflow (cur: eneral protection fault nable to handle kernel ouble fault: RTNL: assertion failed eek! page_mapcount(page) went negative! adness at NETDEV WATCHDOG ysctl table check failed : nobody cared IRQ handler type mismatch Machine Check Exception: Machine check events logged divide error: bounds: coprocessor segment overrun: invalid TSS: segment not present: invalid opcode: alignment check: stack segment: fpu exception: simd exception: iret exception: /var/log/messages -- /usr/bin/abrt-dump-oops -xtD
dbus        724  0.0  0.1  28280  3312 ?        Ss   01:06   0:02 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
chendaj+   6318  0.0  0.1  27808  1928 ?        Ss   07:46   0:00 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
chendaj+   6496  0.0  0.0  26368  1520 ?        S    07:46   0:00 /bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 3
chendaj+   7153  0.0  0.8 1055756 15308 ?       Sl   07:46   0:00 /usr/libexec/evolution-addressbook-factory
chendaj+   7175  0.0  0.8 1299916 16688 ?       Sl   07:46   0:00 /usr/libexec/evolution-addressbook-factory-subprocess --factory local --bus-name org.gnome.evolution.dataserver.Subprocess.Backend.AddressBookx7153x2 --own-path /org/gnome/evolution/dataserver/Subprocess/Backend/AddressBook/7153/2
root      10290 39.0  5.5 210360 103044 pts/9   D+   10:33   0:00 dd if=/dev/zero of=/a.txt count=10 bs=100M
root      10293  0.0  0.0 112680   984 pts/0    R+   10:33   0:00 grep --color=auto dd

2、uptime查看系统负载-top动态管理进程

1)uptime查看CPU负载工具

[root@CHENDAJIE ~]# uptime
 10:36:48 up  9:30,  8 users,  load average: 0.01, 0.20, 0.23

弹出消息含义如下:

10:36:48当前时间
up 9:30系统运行时间,说明此服务器连续运行了9个半小时
8 users当前登录用户
load average: 0.01, 0.20, 0.23系统负载,即任务队列的平均长度。三个数值分别为1分钟,5分钟,15分钟前到现在的平均值

【注】如果服务器的CPU为1核心,则load average中的数字 >=3 负载过高,如果服务器的CPU为4核心,则load average中的数字 >=12 负载过高。
经验:单核心,1分钟的系统平均负载不要超过3,就可以,这是个经验值。

2)top命令

[root@CHENDAJIE ~]# top
top - 10:42:47 up  9:36,  8 users,  load average: 0.00, 0.06, 0.16
Tasks: 266 total,   1 running, 264 sleeping,   1 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1867048 total,   216136 free,   843668 used,   807244 buff/cache
KiB Swap:  2097148 total,  2094428 free,     2720 used.   759724 avail Mem 

当有多个CPU时,这些内容可能会超过两行。内容如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
内存信息(第4、5行)

KiB Mem :  1867048 total,   202432 free,   849252 used,   815364 buff/cache
KiB Swap:  2097148 total,  2094436 free,     2712 used.   754084 avail Mem

内容如下:

Mem : 1867048 total物理内存总量
202432 free空闲内存总量
849252 used使用的物理内存总量
815364 buff/cache用作内核缓存的内存量。
和free -k 一个意思
Swap: 2097148 total交换区总量
2712 used使用的交换区总量
2094436 free空闲交换区总量
754600 avail Mem总的可利用内存是多少
[root@CHENDAJIE ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1823         828         198           7         796         736
Swap:          2047           2        2045

【注】:如果swap分区,被使用,那么你的内存不够用了。
第7行进程信息

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
top快捷键:
默认3s刷新一次,按s修改刷新时间
按空格 :立即刷新。
q退出
P:按CPU排序
M:按内存排序
T按时间排序
p: 进程IP,查看某个进程状态
数字键1:显示每个内核的CPU使用率
u/U:指定显示的用户
h:帮助

3)实战1:找出系统中室友CPU最多的进程

运行top , 找出使用CPU最多的进程 ,按大写的P,可以按CPU使用率来排序显示

top - 11:07:04 up 10:00,  6 users,  load average: 0.00, 0.01, 0.05
Tasks: 264 total,   1 running, 262 sleeping,   1 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1867048 total,   188196 free,   847440 used,   831412 buff/cache
KiB Swap:  2097148 total,  2094476 free,     2672 used.   755836 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                  
 10769 root      20   0  157848   2368   1552 R   0.3  0.1   0:00.10 top                                      
     1 root      20   0  191060   3636   2128 S   0.0  0.2   0:02.09 systemd  

4)lsof命令

lsof命令用于查看你进程打开的文件,打开文件的进程,进程打开的端口(TCP、UDP)
-i<条件>:列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件;
例:

[root@CHENDAJIE ~]# vim a.txt
[root@CHENDAJIE ~]# ps -aux | grep a.txt
root       9973  0.0  0.2 151764  5292 pts/0    T    10:10   0:00 vim a.txt
root      10896  0.1  0.2 151760  5316 pts/0    S+   11:13   0:00 vim a.txt
root      10898  0.0  0.0 112680   992 pts/9    R+   11:13   0:00 grep --color=auto a.txt
[root@CHENDAJIE ~]# lsof -p 10896	#一般用于查看木马进程,在读哪些文件
[root@CHENDAJIE ~]# lsof -i :22	#用于查看端口,或查看黑客开启的后门端口是哪个进程在使用
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1000 root    3u  IPv4  22296      0t0  TCP *:ssh (LISTEN)
sshd    1000 root    4u  IPv6  22298      0t0  TCP *:ssh (LISTEN)
sshd    8611 root    3u  IPv4  90961      0t0  TCP localhost:ssh->localhost:60552 (ESTABLISHED)
sshd    9083 root    3u  IPv4  97765      0t0  TCP localhost:ssh->localhost:50645 (ESTABLISHED)
sshd    9877 root    3u  IPv4 105322      0t0  TCP localhost:ssh->localhost:50955 (ESTABLISHED

5)pstree工具使用

pstree:(display a tree of processes)以树状图显示进程,只显示进程的名字,且相同进程合并显示。
格式:pstree 或 pstree -p
以树状图显示进程,还显示进程PID。

[root@CHENDAJIE ~]# pstree -p

3、前后台进程切换- nice进程优先级-实战screen后台执行命令

1) Linux后台进程与前台进程的区别

前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随着消失
后台进程: 也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要与终端交互;Linux的大多数服务器就是用守护进程实现的。比如,Web服务器httpd等。

2)进程的前台与后台运行

跟系统任务相关的几个命令(了解):

&用在一个命令的最后,可以把这个命令放到后台执行.
ctrl + z将一个正在前台执行的命令放到后台,并且暂停.
jobs查看当前有多少在后台运行的进程.它是一个作业控制命令
fg (foreground process)将后台中的命令调至前台继续运行, 如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)
bg(background process)将一个在后台暂停的命令,变成继续执行; 如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

实战恢复被挂起的进程(了解)
1、

[root@CHENDAJIE ~]# vim a.txt

2、按下 ctrl+z

[1]+  已停止               vim a.txt

3、查看vim a.txt的状态

[root@CHENDAJIE ~]# ps -aux | grep vim
root       9973  0.0  0.2 151764  5292 pts/0    T    10:10   0:00 vi a.txt
root      13442  0.0  0.2 151760  5316 pts/9    T    15:14   0:00 vi a.txt
root      13452  0.0  0.0 112676   980 pts/9    S+   15:15   0:00 grep --color=auto vim

4、查看当前有多少在后台运行的进程

[root@CHENDAJIE ~]# jobs
[1]+  已停止               vim a.txt

5、将后台挂起的进程恢复到前台运行

[root@CHENDAJIE ~]# fg 1

3)kill关闭进程

关闭进程3个命令:kill killall pkill
kill关闭进程:kill 进程号 关闭单个进程
killall和pkill 命令用于杀死指定名字的进程
通过信号的方式来控制进程的
kill -l =====> 列出所有支持的信号(了解) 用最多的是: 9 信号

[root@CHENDAJIE ~]# kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

信号编号 信号名
1) SIGHUP 重新加载配置
2) SIGINT 键盘中断 crtl+c
3) SIGQUIT 退出
9) SIGKILL 强制终止
15) SIGTERM 终止(正常结束),缺省信号
18) SIGCONT 继续
19) SIGSTOP 停止
20) SIGTSTP 暂停 crtl+z
例1:kill和killall终止进程

[root@CHENDAJIE ~]# kill -9 2342	#2342为进程的ID号
[root@CHENDAJIE ~]# killall sshd
[root@CHENDAJIE ~]# pkill sshd

4)进程的优先级管理

优先级取值范围为(-20,19),越小优先级越高, 默认优先级是0
命令1:nice 指定程序的运行优先级
格式:nice n command
命令2:renice 改变程序的运行优先级
格式:renice -n pid

例:
1、指定vim的优先级为5

[root@CHENDAJIE ~]# nice -n 5 vim a.txt

2、然后ctrl+z挂起

[1]+  已停止               nice -n 5 vim a.tx

3、通过ps查看这个文件的PID号

[root@CHENDAJIE ~]# ps -aux | grep vim
root       9973  0.0  0.2 151764  5292 pts/0    T    10:10   0:00 vi a.txt
root      13845  0.0  0.2 151760  5320 pts/9    TN   15:47   0:00 vi a.txt
root      13863  0.0  0.0 112676   980 pts/9    S+   15:49   0:00 grep --color=auto vim

4、通过top命令查看优先级

[root@CHENDAJIE ~]# top -p 13845
top - 15:51:04 up 14:44,  5 users,  load average: 0.00, 0.01, 0.05
Tasks:   1 total,   0 running,   0 sleeping,   1 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 
KiB Mem :  1867048 total,   162816 free,   820988 used,   883244 buf
KiB Swap:  2097148 total,  2094616 free,     2532 used.   780520 ava

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+
 13845 root      25   5  151760   5320   2704 T   0.0  0.3   0:00.04

5、改变正在运行的进程的优先级

[root@CHENDAJIE ~]# renice -10 13845
13845 (进程 ID) 旧优先级为 5,新优先级为 -10

6、通过top命令查看此时vim a.txt文件的优先级

[root@CHENDAJIE ~]# top -p 13845    
top - 15:53:06 up 14:46,  5 users,  load average: 0.00, 0.01, 0.05
Tasks:   1 total,   0 running,   0 sleeping,   1 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 
KiB Mem :  1867048 total,   162568 free,   821236 used,   883244 buf
KiB Swap:  2097148 total,  2094616 free,     2532 used.   780272 ava

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+
 13845 root      10 -10  151760   5320   2704 T   0.0  0.3   0:00.04

4、实战,使用screen后台实时执行命令备份命令

实战场景:公司晚上需要备份1T数据,我在xshell上直接执行备份脚本back.sh可以吗? 或直接运行back.sh & 放到后台运行可以吗? 当关了xshell后,back.sh & 还在后台执行吗?
答:xshell长时间连接,如果本地网络偶尔断开或xshell不小心关闭,都会让后台运行的备份命令停止运行的。正确做法使用: srceen

1)screen概述和安装

Screen中有会话的概念,,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。
安装screen软件包

# rpm -ivh /mnt/Packages/screen-4.1.0-0.23.20120314git3c2946.el7_2.x86_64.rpm

或者

[root@CHENDAJIE ~]# yum -y install screen

2)screen使用方法

直接在命令行键入screen命令回车,如下图

[root@CHENDAJIE ~] # screen     #进入
[root@CHENDAJIE ~]#  vim a.txt   #执行命令, 或执行你自己需要运行的备份命令

此时想离开一段时间,但还想让这个命令继续运行
在screen当前窗口键入快捷键Ctrl+a+d 分离出独立的一个会话
半个小时之后回来了,找到该screen会话:

# screen -ls    #查看已经建立的会话ID
There is a screen on:
         44074.pts-1.tivf06      (Detached)
1 Socket in /tmp/screens/S-root.

重新连接会话:

# screen -r 44074    
# exit    #不想使用screen 会话了,执行:exit退出。

【附】:常用screen参数
screen -S test -> 新建一个叫test的会话
screen -ls -> 列出当前所有的会话
screen -r test -> 回到test会话

总结:
1、 进程概述和ps查看进程工具
2、 uptime查看系统负载-top动态管理进程
3、 前后台进程切换- nice进程优先级-实战screen后台执行命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值