进程和线程?

linux下存在process和thread这两种操作系统基本的概念

process是进程;

thread是线程。

@小牛肉这篇文章介绍的非常清楚~

以工厂为例:

进程就像是工厂的一个车间,一个工厂可能有多个车间,每个车间代表CPU正在处理的任务,某一时刻,CPU总在运行一个进程,其它进程处于非运行状态。

车间内要想完成任务,必须得有很多个工人,多个工人协同完成某个任务,每个工人就像系统进程中的工作线程

车间内是有一定空间的,也就是说进程是占内存空间的,而工人共享车间的空间,工作等等都是在同一个车间中,线程也是如此被共享着。

车间内有很多小房间,但空间大小各不相同,有的能容下很多工人(某块内存数据可以被多个线程同时使用),有的只能容下一个工人(某块内存数据只能给一个线程使用),好比进程中有一个线程正在使用一块内存数据,其它线程必须等待这个线程处理完毕,其它线程才能够使用。(车间内某个厕所被人占用了,其他人需要在外面等待,空出来才能使用)

如果出现厕所已经有人在用另一个人不想等待而去抢夺厕所空间,这时就会产生冲突。(线程1占用内存资源,线程2不等待而去抢夺,出现混乱,造成数据冲突,崩溃!)我们可以通过加锁的方式,让另一个人无法抢夺!(进程1将内存主句加锁!)。

如上的锁就是互斥锁的概念(mutex),用于防止线程对内存数据抢夺,防止多个线程同时读写。


多进程:工厂内,多个车间在工作。

多线程:车间内,多个工人在工作。

单线程:车间内,一个工人在干活。

linux进程管理

ps命令

用于报告当前系统进程状态的命令

ps命令主要用于查询进程信息,主要和kill命令搭配,进行对进程的管理和杀死。

  1. 使用ps找出进程号

  2. kill+进程号杀死进程

  3. 重启进程

ps命令可以查询哪些进程正在进行,以及哪些进程已经停止,以及错误的进程(没有正确停止的进程),以及查看进程使用的资源情况。

我们常常结合grep命令用来过滤我们想要的结果!

语法

1
ps [option] [object]

参数

ps的参数有两种类型

第一种带-的参数,第二种不带-的参数

1
2
3
4
5
6
7
8
9
-e:列出所有进程的环境变量,所有信息。
e:列出程序时,显示每个程序所使用的环境变量。
-f:显示UID,PPIP,C与STIME栏位。
f:用ASCII字符显示树状结构,表达程序间的相互关系。
-a:显示所有终端机下执行的程序,除了阶段作业领导者之外。
a:显示现行终端机下的所有程序,包括其他用户的程序。
-u:<用户识别码>:此选项的效果和指定"-U"选项相同。
u:以用户为主的格式来显示程序状况。
x:显示所有程序,不以终端机来区分。

实际使用

1
ps

执行演示

1
2
3
4
[root@localhost ~]# ps
PID TTY TIME CMD
1859 pts/0 00:00:00 bash
1993 pts/0 00:00:00 ps

PID ,代表进程对应的id号码;

CMD,正在执行的系统命令行;

TTY,表示进程所属的控制台号码;

TIME,表示进程所使用的的CPU总时间。

ps组合命令

常用的组合命令,常常与grep结合使用

ps -ef

显示机器所有详细的进程信息

1
ps -ef

执行演示

1
2
3
4
5
6
[root@localhost ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:49 ? 00:00:01 /usr/lib/systemd/systemd --switched-root --
root 2 0 0 13:49 ? 00:00:00 [kthreadd]
root 4 2 0 13:49 ? 00:00:00 [kworker/0:0H]
...

UID,表示实行该命令的用户;

PID,进程的标识号,用于启停进程;

PPID,进程的父进程标识号;

C,表示CPU使用的资源百分比;

STIME,表示进程是在那个终端上执行的;

TIME,表示该进程所使用的CPU总时长;

CMD,正在执行的系统命令行。

ps aux

1
ps aux

执行演示

1
2
3
~ $ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
u0_a194 9024 0.0 0.0 15112 2076 ? S<s 1970 0:00 sshd

%CPU,表示CPU使用情况百分比;

%MEN,表示内存使用进程百分比;

VSZ,该进程使用的swap内存单位;

RSS,表示进程所占用的内存量;

STAT,表示进程此时的状态

  • S:表示终端睡眠中,可以被唤醒;
  • s:进程含有子进程;
  • R:进程正在运行中;
  • D:进程不可中断的睡眠;
  • T:表示进程已终止
  • Z:进程为僵尸进程,即该进程父进程异常;
  • +:前台进程
  • N:低优先级进程
  • <:高优先级进程
  • L:该进程已被锁定

ps -u

显示指定用户的进程

1
ps -u <usr>

执行演示

创建一个新用户,执行vi命令,开启另一个会谈并输出新用户的进程

1
2
3
[root@localhost ~]# useradd usr0
[root@localhost ~]# su - usr0
[usr0@localhost lappland]$ vi 1.txt
1
2
3
4
[root@localhost ~]# ps -u usr0
PID TTY TIME CMD
14784 pts/0 00:00:00 bash
14830 pts/0 00:00:00 vim

ps -eH

显示父进程,子进程目录结构信息

1
ps -eH

执行演示

1
2
3
4
5
6
7
[root@localhost ~]# ps -eH
...
14873 ? 00:00:00 sshd
14892 pts/1 00:00:00 bash
15898 pts/1 00:00:00 bash
15933 pts/1 00:00:00 ps
...

ps -eo

自定义进程查看的格式

1
pid args psr 等等

只查看pid和执行的命令

1
ps -eo pid,cmd

执行演示

1
2
3
4
5
6
7
8
[root@localhost ~]# ps -eo pid,cmd
PID CMD
1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
2 [kthreadd]
4 [kworker/0:0H]
6 [ksoftirqd/0]
7 [migration/0]
8 [rcu_bh]

pstree命令

查看进程树

首次运行可能需要安装

1
yum install psmisc -y

pstree可以结合之前的shell编程来了解

1
2
3
4
5
6
[root@localhost ~]# pstree    
...
├─sshd─┬─sshd───bash───bash───pstree
│ ├─sshd───sftp-server
│ └─sshd───bash───sleep
...

pgrep命令

过滤程序名字查询相关进程,一般用判断程序是否存活

1
pgrep <程序名>

案例

1
2
pgrep ssh
pgrep ssh -l #显示进程名和id号

执行演示

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# pgrep ssh
1038
14873
14877
15849
[root@localhost ~]# pgrep ssh -l
1038 sshd
14873 sshd
14877 sshd
15849 sshd

kill命令

发送相关信号给进程,达到不同的停止效果。

参数

1
-l:列出信号名称。如果在该选项后提供了数字那么假设它是信号名称对应的数字。

信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 列出所有信号名称:
[user2@pc] 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

常用信号

只有第9种信号(SIGKILL)才可以无条件终止进程,其他信号进程都有权利忽略。

1
2
3
4
5
6
7
HUP     1    终端挂断
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \)
KILL 9 强制终止
TERM 15 终止
CONT 18 继续(与STOP相反,fg/bg命令)
STOP 19 暂停(同 Ctrl + Z)

信号使用实例

终止进程(发送15信号)

1
2
kill  <pid>
kill -15 <pid>
案例

usr0用户运行``vi 1.txt`进程

image-20220804154414240

image-20220804154558590

立即停止进程

危险命令,可以杀死所有进程,如僵尸进程

1
kill -9 <pid>

检查进程情况

0信号,常用在脚本中,如果进程正常则正常返回$?值为0,否则为1

1
kill -0 <pid>
案例

usr0执行ping命令,使用0信号检查

image-20220804155304846

killall命令

使用进程的名称来杀死一组进程

pkill命令

可以按照进程名杀死进程

killall不能删除子进程而pkill可以(killall需要杀死多次才可以)。

pkill -t <tty>

通过终端号杀死该终端中的所有进程