一次性讲清楚常考面试题:进程和线程的区别

news2024/11/28 18:39:01

进程是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。

1、进程和线程的关系

 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
 进程作为资源分配的最小单位,资源是分配给进程的,同一进程的所有线程共享该进程的所有资源。
 真正在处理机上运行的是线程。

2、进程与线程的区别

 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行。
 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

3、java进程与线程资源状态排查

在众多业务系统中,基于java的业务系统是最耗费资源的,所以很多情况下都会坚持java进程以及相关线程的资源占用状态,并由此获取是哪些代码导致的,那么如何解决这些问题呢,其实只需要一些命令行的组合即可完成。
首先,需要获取java应用中(以tomcat为例)占用CPU过高的进程,方法上面已经介绍过了,是执行如下命令:

[root@localhost ~]# ps aux|head -1;ps aux|sort -rn -k3|head -1

此命令可以获取占用CPU资源最高的进程,我们记录这个进程的pid,比如说是3016。

tomcat应用中虽然只有一个java进程,但此进程是多线程机制的,通过多线程可以充分利用CPU的多核资源,那么如何查看进程对应的线程信息呢,方法很多,常用的命令有ps、top和htop命令。这里使用htop命令,通过控制台选项调出线程信息,如下图所示:

 

很简单吧,这样就可以清楚看到单个进程的线程视图了,并且状态信息也是实时刷新的。通过这个方法也可以查找出CPU利用率最厉害的线程号。然后记录下来。

接着,从上图找到最消耗CPU资源的java线程的id号,将线程的pid转换为16进制数:

[root@localhost ~]#printf ‘%x\n’ tid

注意,此处的tid为上一步找到的占CPU高的线程号。

最后一步,还需要一个java工具jstack,jstack是java虚拟机自带的一种堆栈跟踪工具。可以用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。

总结一句话:jstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁)。

想要通过jstack命令来分析线程的情况的话,首先要知道线程都有哪些状态,下面这些状态是我们使用jstack命令查看线程堆栈信息时可能会看到的线程的几种状态:

 NEW,未启动的。不会出现在Dump中。
 RUNNABLE,在虚拟机内执行的。运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。
 BLOCKED,受阻塞并等待监视器锁。被某个锁(synchronizers)給block住了。
 WATING,无限期等待另一个线程执行特定操作。等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。
 TIMED_WATING,有时限的等待另一个线程的特定操作。和WAITING的区别是wait()等语句加上了时间限制wait(timeout)。
 TERMINATED,已退出的。

那么怎么去使用jstack呢,很简单,用jstack打印线程信息 ,将信息重定向到文件中,可执行如下操作:

[root@localhost ~]# jstack pid |grep tid

例如:

[root@localhost ~]# jstack 30116 |grep 75cf >> jstack.out

这里的“75cf “就是线程的tid转换为16进制数的结果。
下面是jstack的输出信息:

"main" #1 prio=5 os_prio=0 tid=0x00007f9cb800a000 nid=0xbc9 runnable [0x00007f9cbf1d4000]
   java.lang.Thread.State: RUNNABLE
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
        at java.net.ServerSocket.implAccept(ServerSocket.java:545)
        at java.net.ServerSocket.accept(ServerSocket.java:513)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:466)
        at org.apache.catalina.startup.Catalina.await(Catalina.java:769)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:715)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:353)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493)

   Locked ownable synchronizers:
        - None

这里面重点关注下输出的线程状态,如果有异常,会输出相关异常信息或者跟程序相关的信息,将这些信息给的开发人员,就可以马上定位CPU过高的问题,所以这个方法非常有效。

4、查询当前整个系统每个进程的线程数

我们经常遇到这样的问题,比如某台服务器的CPU使用率飙升,通过top或htop命令查看是某个程序(例如java)占用的cpu比较大,现在需要查询java各个进程下的线程数情况。可以通这一个命令组合实现:

[root@localhost ~]# for pid in $(ps -ef|grep -v grep|grep "java"|awk '{print $2}');do echo ${pid} > /tmp/a.txt ;cat /proc/${pid}/status|grep Threads > /tmp/b.txt;paste /tmp/a.txt /tmp/b.txt;done|sort -k3 -rn 

先解释下这个脚本:

1)、for pid in $(ps -ef|grep -v grep|grep java |awk '{print $2}')
这部分是获取${pid}变量为java进程的pid号。
2)、echo ${pid} > /tmp/a.txt
这部分是将java进程的pid号都打印到/tmp/a.txt文件中。
3)、cat /proc/${pid}/status|grep Threads > /tmp/b.txt
这部分是将各个pid进程号下的线程信息打印到/tmp/b.txt文件中。
4)、paste /tmp/a.txt /tmp/b.txt
这部分是以列的形式展示a.txt和b.txt文件中的信息。
5)sort -k3 -rn
这部分是对输出的信息进行排序,其中,-k3表示以第三列进行排序,“-rn”表示降序排列。

将上面命令组合放入系统执行完毕后,输入内容如下:

 从输出可以看出,第一列显示的是java的进程号,最后一列显示的每个java进程对应的线程数量。

这个例子是一个for循环加上ps命令和sort命令综合应用的实例。

更多Linux、云计算、云原生、大数据、docker、k8s知识,可访问:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/763759.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

今天实习第三天,vue(vue-cli部分,webpack部分,vue-router部分,elementUI部分)

01.创建第一个vue-cli。这里用的是node.js。早上的时候,就需要把node.js安装上去 02.node.js安装 第一步.去官网下载node.js https://nodejs.org/en 第二步.运行官网下载的node.js的msi文件(记住所有的node.js文件的安装包都是msi文件的形式&#xff0…

(学习笔记-TCP连接建立)IP层会分片,为什么TCP层还需要MSS呢?

前提知识: 网络层最常用的是IP协议,IP协议会将传输层的报文作为数据部分,再加上IP包头组装成IP报文,如果IP报文大小超过了MTU(1500字节)就会再次分片,得到一个即将发送到网络的IP报文 MTU和MSS: MTU:一个网…

如何在 Excel 中快速生成随机密码?

有时,我们可能想创建随机密码来保护某些重要内容。 但是,您有什么技巧可以在Excel中快速生成随机密码? 在这里,我有一些可以在Excel工作表中处理的方法。 用公式生成随机密码 使用插入随机数据生成随机密码​编辑 用公式生成随机…

普通人的姓名可以注册为商标吗?

商标是商品的生产者、经营者在其生产、制造、加工或者经销的商品上或者服务使用的标志,用于区别商品或服务来源。商标由文字、图形、字母、数字、三维标志、颜色组合和声音等组合而成,以姓名注册商标属于文字商标,因此,个人的名字…

第十二章:MULTI-SCALE CONTEXT AGGREGATION BY DILATED CONVOLUTIONS——通过膨胀卷积的多尺度上下文聚合

0.摘要 目前用于语义分割的先进模型是基于最初设计用于图像分类的卷积网络的改进。然而,像语义分割这样的密集预测问题在结构上与图像分类不同。在这项工作中,我们开发了一个专门为密集预测设计的新的卷积网络模块。所提出的模块使用膨胀卷积来系统地聚合…

QQ号码3个月未登陆真的要回收?

7月17日消息,微信号长期未使用会被回收的消息引起热议。 腾讯微信团队微博发文称:为保障用户的微信账号安全,注册后不活跃,长期未登录,并且没有零钱的微信账号,会被系统注销,无法使用。 不过也有…

B. The BOSS Can Count Pairs

Problem - 1830B - Codeforces 思路&#xff1a;因为ai*ajbibj&#xff0c;bibj<2*n&#xff0c;那么会有ai*aj<2*n&#xff0c;那么会有min(ai,aj)<sqrt(2*n)&#xff0c;我们能够发现我们只要枚举ai&#xff08;假设ai<aj&#xff09;那么只要在这种情况下求得所…

Kubernetes(K8s)常用命令大全:熟练编排更完美

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

提升效率,打通万里牛ERP与下游用友U8财务软件的无缝对接

一、对接流程 1.1 销售/售后流程 在万里牛订单出库后&#xff0c;通过轻易云数据集成平台将数据推送至用友U8销售订单和销售出库单&#xff0c;这些单据可以进行关联操作。 当万里牛售后单完成退货入库后&#xff0c;通过数据集成平台将数据推送至用友U8销售退货单和红字销售…

基于SpringBoot+vue的点餐平台网站设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

编程导航算法通关村第 1关 | 单链表的操作

编程导航算法通关村第 1关 | 链表的操作 文章目录 编程导航算法通关村第 1关 | 链表的操作单链表链表的定义初始化链表的遍历获取链表的长度链表的插入链表的节点的删除 双向链表节点的定义双向链表的定义节点的打印获取长度头部插入元素尾部插入元素链表的删除 单链表 链表的…

InnoDB锁内存结构

假如说 我们SELECT * FROM table WHERE a < 10000 FOR UPDATE 那岂不是要加几万条锁 这消耗老鼻子内存了 这些锁有很多地方都是一样的啊 能不能通过某种方式整理整理节省点内存呢? 答案是能 如果符合下边这些条件&#xff1a; 在同一个事务中进行加锁操作 被加锁的记录…

Redis远程字典服务

目录 前言 1.NoSQL 1.1NOSQL和关系型数据库比较 1.2非关系型数据库的优势 1.3关系型数据库的优势 ​编辑 2.主流的NOSQL产品 键值(Key-Value)存储数据库 列存储数据库 文档型数据库 图形(Graph)数据库 3.Redis简介 redis的应用场景 4.命令操作 4.1字符串类型 s…

python根据excel数据,基于散点图绘制棋盘图

文章目录 一、需求二、处理方式三、代码实现 一、需求 根据可视化的需要&#xff0c;下图的数据需要使用棋盘图的样式来展示&#xff0c; 原始数据&#xff1a; 最终效果图&#xff1a; 二、处理方式 1、先将DataFrame数据转换为Numpy数组&#xff1b; 2、先使用np.transp…

Window下Mysql5.x和8.x版本切换

在最近的工作中需要使用Mysql5.x版本&#xff0c;但以前的自己项目开发使用的Mysql版本都是8.x。因此特意去查资料看了一下&#xff0c;下边是如何在window下实现两个不同版本Mysql的切换。 既然是不同的Mysql&#xff0c;所以我们需要去下载自己需要的Mysql版本安装即可。&…

立思辰打印机IP连接和USB连接

打印机是常用办公设备,很多家庭也都用着这个,立思辰3032是一个比较老的型号,属于国产打印机,基本功能都有,下边分享一下安装经验: 1.驱动: 不管是连USB还是IP地址,都需要先给电脑装上打印机驱动,只有装上驱动,系统才能够识别打印机,并帮助用户传输文件。一般来讲,立…

Jenkins动态化阶段步骤

Jenkins中如何去根据入参动态化阶段步骤呢&#xff1f; Groovy语言基础 定义一个列表变量 def list []定义一个map的kv结构变量 def map [:]如何可以动态化阶段步骤 动态化步骤&#xff1a;其实就是&#xff0c;在jenkins pipeline中根据入参或者其他变量列表&#xff0c;动…

进阶高级Python开发工程师,不得不掌握的Python高并发编程(文末送书5本)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Vue 项目路由、自定义指令、api方法自动引入资源(require.context使用)

前端项目&#xff08;当前我以Vue项目为例&#xff09;当我们把api挂载在main上后 // 将api挂载到vue的原型上 import api from /api Vue.prototype.$apiapi在src下会有一个api文件夹&#xff0c;结构如下&#xff1a; 通常情况下&#xff0c;api文件夹的index.js文件我们通常…

Morris遍历--验证二叉搜索树(java)

Morris遍历- 验证二叉搜索树题目描述Morris 遍历解题代码演示&#xff1a; morris 遍历改写后序遍历 验证二叉搜索树 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/validate-binary-search-tree 题目描述 给你一个二叉…