精华内容
下载资源
问答
  • 进程线程的区别(超详细)

    万次阅读 多人点赞 2019-10-03 21:57:46
    进程和线程 进程 一个在内存运行的应用...一个进程至少有一个线程一个进程可以运行多个线程,多个线程可共享数据。 与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟...

    进程和线程

    进程

    一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。

    任务管理器

    线程

    进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。

    与进程不同的是同类的多个线程共享进程的方法区资源,但每个线程有自己的程序计数器虚拟机栈本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

    Java 程序天生就是多线程程序,我们可以通过 JMX 来看一下一个普通的 Java 程序有哪些线程,代码如下。

    public class MultiThread {
    	public static void main(String[] args) {
    		// 获取 Java 线程管理 MXBean
    		ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    		// 不需要获取同步的 monitor 和 synchronizer 信息,仅获取线程和线程堆栈信息
    		ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
    		// 遍历线程信息,仅打印线程 ID 和线程名称信息
    		for (ThreadInfo threadInfo : threadInfos) {
    			System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
    		}
    	}
    }
    

    上述程序输出如下(输出内容可能不同,不用太纠结下面每个线程的作用,只用知道 main 线程执行 main 方法即可):

    [6] Monitor Ctrl-Break //监听线程转储或“线程堆栈跟踪”的线程
    [5] Attach Listener //负责接收到外部的命令,而对该命令进行执行的并且把结果返回给发送者
    [4] Signal Dispatcher // 分发处理给 JVM 信号的线程
    [3] Finalizer //在垃圾收集前,调用对象 finalize 方法的线程
    [2] Reference Handler //用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收的线程
    [1] main //main 线程,程序入口
    

    从上面的输出内容可以看出:一个 Java 程序的运行是 main 线程和多个其他线程同时运行

    进程与线程的区别总结

    线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。

    根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

    资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

    包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

    内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

    影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

    执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行

    从 JVM 角度说进程和线程之间的关系(重要)

    图解进程和线程的关系

    下图是 Java 内存区域,通过下图我们从 JVM 的角度来说一下线程和进程之间的关系。

    在这里插入图片描述

    从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器虚拟机栈本地方法栈

    程序计数器为什么是私有的?

    程序计数器主要有下面两个作用:

    1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
    2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。

    需要注意的是,如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。

    所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置

    虚拟机栈和本地方法栈为什么是私有的?

    • 虚拟机栈:每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
    • 本地方法栈:和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

    所以,为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地方法栈是线程私有的。

    一句话简单了解堆和方法区

    堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象 (所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    多进程和多线程区别

    多进程:操作系统中同时运行的多个程序

    多线程:在同一个进程中同时运行的多个任务

    举个例子,多线程下载软件,可以同时运行多个线程,但是通过程序运行的结果发现,每一次结果都不一致。 因为多线程存在一个特性:随机性。造成的原因:CPU在瞬间不断切换去处理各个线程而导致的,可以理解成多个线程在抢CPU资源。

    多线程提高CPU使用率

    多线程

    多线程并不能提高运行速度,但可以提高运行效率,让CPU的使用率更高。但是如果多线程有安全问题或出现频繁的上下文切换时,运算速度可能反而更低。

    Java中的多线程

    Java程序的进程里有几个线程:主线程,垃圾回收线程(后台线程)等

    在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。

    Java支持多线程,当Java程序执行main方法的时候,就是在执行一个名字叫做main的线程,可以在main方法执行时,开启多个线程A,B,C,多个线程 main,A,B,C同时执行,相互抢夺CPU,Thread类是java.lang包下的一个常用类,每一个Thread类的对象,就代表一个处于某种状态的线程

    展开全文
  • 一个进程中线程的堆和栈的关系

    千次阅读 2014-03-13 13:56:12
    在很多现代操作系统一个进程的(虚)地址空间大小为4G,分为系统空间和用户空间两部分,系统空间为所有进程共享,而...堆(heap)的分配与栈有所不同,一般是一个进程有一个C运行时堆,这个堆为本进程中所有线程
    
    
    在很多现代操作系统中,一个进程的(虚)地址空间大小为4G,分为系统空间和用户空间两部分,系统空间为所有进程共享,而用户空间是独立的,一般WINDOWS进程的用户空间为2G。
      一个进程中的所有线程共享该进程的地址空间,但它们有各自独立的(私有的)栈(stack),Windows线程的缺省堆栈大小为1M。堆(heap)的分配与栈有所不同,一般是一个进程有一个C运行时堆,这个堆为本进程中所有线程共享,Windows进程还有所谓进程默认堆,用户也可以创建自己的堆。
    堆: 是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。

    栈:是个线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立,因此,栈是 thread safe的。操作系统在切换线程的时候会自动的切换栈,就是切换 SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

    进程线程及堆栈关系的总结

    突然想到进程的栈和线程的栈,就顺便说一下,线程的栈被自动分配到进程的内存空间中

    进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于: 

    简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 
    线程的划分尺度小于进程,使得多线程程序的并发性高。 
    另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 
    线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 
    从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。 

    进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 
    线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 
    一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

    ============================================================

    堆: 是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。


    栈:是个线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立,因此,栈是 thread safe的。每个C ++对象的数据成员也存在在栈中,每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换 SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

    堆和栈的区别

    一、预备知识—程序的内存分配

    一个由c/C++编译的程序占用的内存分为以下几个部分:
    1、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

    2、堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。

    4、文字常量区   —常量字符串就是放在这里的。程序结束后由系统释放。

    5、程序代码区—存放函数体的二进制代码。

    二、例子程序 //main.cpp
    int a = 0; 全局初始化区
    char *p1; 全局未初始化区
    main()
    {
    int b; 栈
    char s[] = "abc"; 栈
    char *p2; 栈
    char *p3 = "123456"; 123456\0在常量区,p3在栈上。
    static int c =0;全局(静态)初始化区
    p1 = (char *)malloc(10);
    p2 = (char *)malloc(20);
    分配得来得10和20字节的区域就在堆区。
    strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
    }二、堆和栈的理论知识
    2.1申请方式
    stack:
    由系统自动分配。例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
    heap:
    需要程序员自己申请,并指明大小,在c中malloc函数
    如p1 = (char *)malloc(10);
    在C++中用new运算符
    如p2 = (char *)malloc(10);
    但是注意p1、p2本身是在栈中的。


    2.2
    申请后系统的响应
    栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
    堆: 首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲 结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

    2.3申请大小的限制
    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也可能是1M,它是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小

    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。


    2.4申请效率的比较:
    栈由系统自动分配,速度较快。但程序员是无法控制的。
    堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
    另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

    2.5堆和栈中的存储内容
    栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
    当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
    堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

    2.6存取效率的比较

    char s1[] = "aaaaaaaaaaaaaaa";
    char *s2 = "bbbbbbbbbbbbbbbbb";
    aaaaaaaaaaa是在运行时刻赋值的;
    而bbbbbbbbbbb是在编译时就确定的;
    但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
    比如: void main()
    {
    char a = 1;
    char c[] = "1234567890";
    char *p ="1234567890";
    a = c[1];
    a = p[1];
    return;
    }对应的汇编代码 10: a = c[1];
    00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
    0040106A 88 4D FC mov byte ptr [ebp-4],cl
    11: a = p[1];
    0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
    00401070 8A 42 01 mov al,byte ptr [edx+1]
    00401073 88 45 FC mov byte ptr [ebp-4],al第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据
    edx读取字符,显然慢了。


    2.7小结:
    堆和栈的区别可以用如下的比喻来看出:
    使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
    使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

    展开全文
  • 进程与线程的关系 简单复习一下:一个”进程“代表计算机实际跑起来的一个程序,在现代操作系统...因此一个进程至少有一个线程,我们把这个线程称之为”主线程“,也就是说,一个进程至少有一个主线程。 ...

    进程与线程的关系

    简单复习一下:一个”进程“代表中计算机中实际跑起来的一个程序,在现代操作系统的保护模式下,每个进程拥有自己独立的进程地址空间和上下文堆栈。但是就一个程序本身执行的操作来说,进程其实什么也不做(不执行任何进程代码),它只是提供一个大环境容器,在进程中实际的执行体是”线程“。因此一个进程至少得有一个线程,我们把这个线程称之为”主线程“,也就是说,一个进程至少要有一个主线程。

     

    进程中创建线程的限制

    默认情况下,一个线程的栈要预留1M的内存空间,而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程。但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小。

    #include "stdafx.h"
    #include <windows.h>
    #include <process.h>
    #include <assert.h>
    
    #define DEFAULT_STACK//注释该行,则开辟的线程默认栈大小为512KB
    
    volatile bool g_bExitThread = false;
    HANDLE g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    
    UINT WINAPI WorkThread(void* ptr)
    {
    	int nThreadID = *((int*)ptr);	
    	printf("%d线程启动\n", nThreadID);
    
    	SetEvent(g_hEvent);
    	while(!g_bExitThread)
    	{
    		Sleep(1);//权宜之计,让线程不要提前退出
    	}
    
    	return 0;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	for(int i=0; i<5000; i++)
    	{
    
    #ifdef DEFAULT_STACK
    		HANDLE _handle = (HANDLE)_beginthreadex(NULL, 0, WorkThread, &i, 0, NULL);
    #else
    		HANDLE _handle = (HANDLE)_beginthreadex(NULL, 512*1024, WorkThread, &i, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
    #endif		
    		
    		if (_handle == 0)
    		{
    			if(GetLastError() == 8)
    			{
    				printf("开启线程失败,存储空间不足!\n");
    			}
    			else
    			{
    				printf("开启线程失败,错误号%d\n", GetLastError());
    			}
    			break;
    		}
    		WaitForSingleObject(g_hEvent, INFINITE);
    	}
    	getchar();
    	return 0;
    }

    使用默认的线程栈大小(1M),从输出结果来看,一个进程最大能开辟的线程数为:1451

    将上面代码的“#define DEFAULT_STACK”注释掉,使用线程的栈大小改为512KB。从输出结果来看,一个进程最大能开辟的线程数为:2284

     

    如何突破2000个限制

    可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。 如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。但即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制。比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用的还是2GB。

    如果是同一台机器内的话,能起多少线程也是受内存限制的。每个线程对象都要占用非页面内存,而非页面内存也是有限的,当非页面内存被耗尽时,也就无法创建线程了。如果物理内存非常大,同一台机器内可以跑的线程数目的限制值会越来越大。


     

    展开全文
  • 如何查询一个进程下面的线程数(进程线程区别) https://www.cnblogs.com/kevingrace/p/5252919.html在平时工作,经常会听到应用程序的进程线程的概念,那么它们两个之间究竟什么关系或不同呢?一、对比...

    如何查询一个进程下面的线程数(进程和线程区别)

     https://www.cnblogs.com/kevingrace/p/5252919.html

    在平时工作中,经常会听到应用程序的进程和线程的概念,那么它们两个之间究竟有什么关系或不同呢?
    一、对比进程和线程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    1)两者概念
    . 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
    . 线程是指进程内的一个执行单元,也是进程内的可调度实体. 线程是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位线程自己基本上不拥有系统资源,只拥有一点
      在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
     
    2)两者关系
    . 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
    . 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
     
    3)两者区别
    进程和线程的主要差别在于它们是不同的操作系统资源管理方式:进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响;而线程只是一个进程中的不同执行路径。
    线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差
    一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
     
    进程和线程的区别:
    . 地址空间:线程是进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;
    . 资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
    . 线程是处理器调度的基本单位,但进程不是.
    . 进程和线程二者均可并发执行.
    . 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
    . 线程的划分尺度小于进程,使得多线程程序的并发性高。
    . 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
    . 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个
      线程执行控制。
    . 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就
      是进程和线程的重要区别。
     
    4)优缺点
    线程和进程在使用上各有优缺点:
    . 线程执行开销小,但不利于资源的管理和保护;而进程正相反。
    . 线程适合于在SMP机器上(即对称多处理结构的简称,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构)运行,而进程则可以跨机器迁移。

    二、如何查看某个进程的线程数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    有些时候需要确定进程内部当前运行了多少线程,查询方法如下:
      
    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中目录的总数表示在进程中线程的数目。

    比如某台服务器的CPU使用率飙升,通过top命令查看是gitlab程序占用的cpu比较大,"ps -ef|grep gitlab"发现有很多个gitlab程序,现在需要查询gitlab各个进程下的线程数情况。批量查询命令如下:
    for pid in $(ps -ef|grep -v grep|grep gitlab|awk '{print $2}');do echo ${pid} > /root/a.txt ;cat /proc/${pid}/status|grep Threads > /root/b.txt;paste /root/a.txt /root/b.txt;done|sort -k3 -rn

    脚本解释:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    1)for pid in $(ps -ef|grep -v grep|grep gitlab|awk '{print $2}')
    定义${pid}变量为gitlab进程的pid号
     
    2)echo ${pid} > /root/a.txt
    将http进程的pid号都打印到/root/a.txt文件中
     
    3)cat /proc/${pid}/status|grep Threads > /root/b.txt
    将各个pid进程号下的线程信息打印到/root/b.txt文件中
     
    4)paste /root/a.txt /root/b.txt
    以列的形式展示a.txt和b/txt文件中的信息
     
    5)sort -k3 -rn
    -k3  表示以第三列进行排序
    -rn  表示降序

    展开全文
  • 一个JVM进程启动后里面几个线程

    千次阅读 2012-07-24 09:16:48
    但是我们写的这个所谓的单线程程序只是JVM这个程序一个线程,JVM本身是一个线程的程序,至少有一个垃圾收集器线程吧。  刚装了一个NetBeans6.0,里面带了一个分析器包,于是写了一个HelloWorld程序,检验...
  • 第二,进程一个“执行的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程进程状态:进程有三个状态,就绪、运行、阻塞。 511遇见易语言多线程大漠多...
  • Android App进程中最少个线程

    千次阅读 2019-03-26 14:48:03
    当应用程序组件启动,且应用程序没有其他组件运行时,Android系统为这个应用程序启动一个新的Linux进程,并开始运行一个主线程。默认情况下,同一应用程序的所有组件都在同一进程的主线程运行。如果应用程序组件...
  • 一个进程最多能包含多少线程

    万次阅读 2012-10-20 16:22:34
    实验蛮简单的,但是,我不由想到了,一个进程最多能包含多少个线程。 在网上查了查,貌似也没找到多少这方面的资料。大部分都是关于服务器多线程链接sever的,关于本机可执行exe的进程数倒是没有什么涉及。 我觉得...
  • 用现实中一个实例来解释进程线程,以及他们之间的关系.
  • 进程线程

    千次阅读 2018-08-16 10:51:31
    线程 引入线程可提高程序并发执行的程度,可进一步提高系统效率 。...一个进程至少包含一个主线程(线程数量大于等于1)。 由于同一进程的多个线程具有相同的地址空间,所以它们间的同步和通信也易...
  • 线程进程的区别?

    万次阅读 多人点赞 2019-05-13 10:56:11
    一个程序至少一个进程,一个进程至少一个线程 每个进程都独立的内存地址空间;系统不会为线程分配内存,线程组之间只能共享所属进程的资源 程序之间的切换会较大的开销;线程之间切换的开销小 【Java面试题...
  • 进程线程

    千次阅读 2021-02-07 19:12:12
    1、一个线程只能属于一个进程,而一个进程可以多个线程,但至少有一个线程(主线程)。 2、资源分配给进程,同一进程的所有线程共享该进程的所有资源。 3、线程在执行过程需要协作同步。 4、CPU分给线程,即真正...
  • 最近部门新招过来的校招生问了我一个问题:“为什么redis进行RDB持久化数据时,新起一个进程而不是在原进程中一个线程来持久化数据”。好吧,那今天我们就来讨论讨论这个问题。
  • iOS 中线程进程的区别

    千次阅读 2015-10-10 21:35:53
     (1)一个线程只能属于一个进程,而一个进程可以多个线程,但至少有一个线程线程是操作系统可识别的最小执行和调度单位。  (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多...
  • 线程进程、多线程、多进程 和 多任务 小结

    千次阅读 多人点赞 2019-04-20 11:59:56
    5 线程进程的关系 6 线程进程的区别 7 进程的优缺点 7.1 进程的优点 7.2 进程的缺点 8 线程的优缺点 8.1 线程的优点 8.2 线程的缺点 9 多线程的优缺点 9.1 多线程的优点 9.2 多线程的缺点 10多进程的...
  • 线程进程

    千次阅读 2016-08-07 12:45:41
    线程进程中执行运算的最小单位,是进程中一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源...
  • 进程里的堆,是一个进程中最大的一块内存,被进程中的所有线程共享的,进程创建时分配,主要存放 new 创建的对象实例 进程里的方法区,是用来存放进程中的代码片段的,是线程共享的 在多线程 OS 进程不是一个...
  • 一个故事讲完进程线程和协程

    千次阅读 多人点赞 2018-05-28 08:29:27
    一个故事讲完进程线程和协程很久以前,两个程序,暂且称他们旺财和小强吧。旺财和小强这两个程序都很长,每个都十几万行。 他们两个的人生价值就是到CPU上去运行,把运行结果告诉人类。CPU是稀缺资源,只有...
  • 进程线程的深入理解

    万次阅读 多人点赞 2019-04-25 00:14:40
    之前,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。 1.计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。 2.假定工厂的电力有限,一次只能供给一个车间使用。也就是...
  • java多线程):进程线程

    千次阅读 2015-05-28 15:22:43
    (在java的一个程序至少两个线程一个是主线程,一个是称为垃圾回收的线程的后台线程)   2、线程:是指进程中一个执行任务(控制单元),一个进程可以运行多个线程,多个线程可共享数据。  理解线程:...
  • 进程线程一个简单解释

    千次阅读 2013-05-07 22:16:16
    最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂。 1. 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。 2. 假定工厂的电力有限,一次只能...
  • 线程进程

    千次阅读 2017-09-02 18:51:36
    线程自己基本上不拥有系统资源,只拥有一点在运行必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.2.关系一个线程可以创建和撤销另一个线
  • 进程线程、死锁

    万次阅读 2018-04-18 11:05:29
    一个进程有一个自己的地址空间,即进程空间或(虚空间)。进程有 5 种基本状态:创建、就绪、阻塞、执行、终止。            线程   线程:CPU调度的一个基本单位。线程与同属一个进程的其他...
  • Android进程线程

    千次阅读 2016-06-01 15:00:46
    一个Android应用就是一个Linux进程,每个应用在各自的进程中运行,互不干扰,比较安全。一个应用对应一个主线程,就是通常所说的UI线程,android遵守的就是单线程模型,所以说Ui操作不是线程安全的并且这些操作必须...
  • 进程线程有什么区别

    千次阅读 2015-03-14 19:44:40
    1.进程线程 1.1 概述: ...线程自己基本上不拥有系统资源,只拥有一点在运行必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 一个
  • 深入理解进程线程

    千次阅读 2015-10-30 23:40:52
    在之前的博客里面(进程通信),我简单的区分了一下...线程是CPU运行调度的基本单位,线程必须被包含在进程中一个进程可以很多线程至少有一个),这些线程有自己的资源(如栈,寄存器)也共享进程的许多资源。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 153,245
精华内容 61,298
关键字:

一个进程中至少有一个线程