在平时工作中, 经常会听到应用程序的进程和线程的概念, 那么它们两个之间究竟有什么关系或不同呢?
一, 深入理解进程和线程的区别
1)两者概念
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动, 进程是系统进行资源分配和调度的一个独立单位.
线程是指进程内的一个执行单元, 也是进程内的可调度实体. 线程是 CPU 调度和分派的基本单位, 它是比进程更小的能独立运行的基本单位线程自己基本上不拥有系统资源, 只拥有一点
在运行中必不可少的资源(如程序计数器, 一组寄存器和栈), 但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
2)两者关系
一个线程可以创建和撤销另一个线程; 同一个进程中的多个线程之间可以并发执行.
相对进程而言, 线程是一个更加接近于执行体的概念, 它可以与同进程中的其他线程共享数据, 但拥有自己的栈空间, 拥有独立的执行序列.
3)两者区别
进程和线程的主要差别在于它们是不同的操作系统资源管理方式: 进程有独立的地址空间, 一个进程崩溃后, 在保护模式下不会对其它进程产生影响; 而线程只是一个进程中的不同执行路径.
线程有自己的堆栈和局部变量, 但线程之间没有单独的地址空间, 一个线程死掉就等于整个进程死掉, 所以多进程的程序要比多线程的程序健壮, 但在进程切换时, 耗费资源较大, 效率要差
一些. 但对于一些要求同时进行并且又要共享某些变量的并发操作, 只能用线程, 不能用进程.
进程和线程的区别:
. 地址空间: 线程是进程内的一个执行单元; 进程至少有一个线程; 它们共享进程的地址空间; 而进程有自己独立的地址空间;
. 资源拥有: 进程是资源分配和拥有的单位, 同一个进程内的线程共享进程的资源
. 线程是处理器调度的基本单位, 但进程不是.
. 进程和线程二者均可并发执行.
. 简而言之, 一个程序至少有一个进程, 一个进程至少有一个线程.
. 线程的划分尺度小于进程, 使得多线程程序的并发性高.
. 另外, 进程在执行过程中拥有独立的内存单元, 而多个线程共享内存, 从而极大地提高了程序的运行效率.
. 线程在执行过程中与进程还是有区别的. 每个独立的线程有一个程序运行的入口, 顺序执行序列和程序的出口. 但是线程不能够独立执行, 必须依存在应用程序中, 由应用程序提供多个
线程执行控制.
. 从逻辑角度来看, 多线程的意义在于一个应用程序中, 有多个执行部分可以同时执行. 但操作系统并没有将多个线程看做多个独立的应用, 来实现进程的调度和管理以及资源分配. 这就
是进程和线程的重要区别.
4)优缺点
线程和进程在使用上各有优缺点:
. 线程执行开销小, 但不利于资源的管理和保护; 而进程正相反.
. 线程适合于在 SMP 机器上 (即对称多处理结构的简称, 是指在一个计算机上汇集了一组处理器(多 CPU), 各 CPU 之间共享内存子系统以及总线结构) 运行, 而进程则可以跨机器迁移.
二, 如何查看某一进程的线程数
有些时候需要确定进程内部当前运行了多少线程, 查询方法如下:
1)通过 pstree 命令 (根据 pid) 进行查询:
- [root@xqsj_web2 ~]# ps -ef|grep java // 查找进程 pid(比如这里查找 java(tomcat)进程的 pid)
- [root@xqsj_web2 ~]# pstree -p 19135
- java(19135){java}(19136)
- {java}(19137)
- .......
- {java}(13578)
- [root@xqsj_web2 ~]# pstree -p 19135|wc -l
- 46 // 由于第一行包括了 2 个线程, 所以该进程下一共有 47 个线程!
或者使用 top 命令查看(可以查看到线程情况)
[root@xqsj_web2 ~]# top -Hp 19135 // 下面结果中的 Tasks 对应的 47 即是线程的个数
top - 14:05:55 up 391 days, 20:59, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 47 total, 0 running, 47 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 0.1%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 8058056k total, 7718656k used, 339400k free, 354216k buffers
Swap: 0k total, 0k used, 0k free, 4678160k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19135 root 20 0 5339m 632m 5476 S 0.0 8.0 0:00.00 java
19136 root 20 0 5339m 632m 5476 S 0.0 8.0 0:00.84 java
......
2)根据 ps 命令直接查询:
- [root@xqsj_web2 ~]# ps hH p 19135| wc -l
- 47
3)通过查看 / proc/pid/status
proc 伪文件系统, 它驻留在 / proc 目录, 这是最简单的方法来查看任何活动进程的线程数./proc 目录以可读文本文件形式输出, 提供现有进程和系统硬件
相关的信息如 CPU, 中断, 内存, 磁盘等等.
- [root@xqsj_web2 ~]# cat /proc/19135/status
- Name: java
- State: S (sleeping)
- Tgid: 19135
- Pid: 19135
- PPid: 1
- TracerPid: 0
- ........
- Threads: 47 // 这里显示的是进程创建的总线程数. 输出表明该进程有 47 个线程.
- SigQ: 1/62793
- SigPnd: 0000000000000000
- ShdPnd: 0000000000000000
- .......
voluntary_ctxt_switches: 1
nonvoluntary_ctxt_switches: 1
或者, 也可以在 / proc//task 中简单的统计子目录的数量, 如下所示:
[root@xqsj_web2 ~]# ll /proc/19135/task
总用量 0
dr-xr-xr-x 6 root root 0 6 月 14 17:57 11553
- ......
- [root@xqsj_web2 ~]# ll /proc/19135/task|wc -l
- 48
这是因为, 对于一个进程中创建的每个线程, 在 / proc/<pid>/task 中会创建一个相应的目录, 命名为其线程 ID. 由此在 / proc/<pid>/task 中目录的总数表示在进程中线程的数目.
来源: http://www.bubuko.com/infodetail-2593836.html