线程:是进程中某个单一顺序的控制流也称为light weight processes)

线程是操作系统能够进行运算调度的最小单位,她被包含在进程之中,是进程中的实际操作单位,一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,线程可以操作系统内核调度的内核线程。

同一个进程的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等

但是同一进程中的多个线程有各自的调用栈,自己的寄存器环境,自己的线程本地存储。

线程和进程的区别在  :通常一个进程中可以包含多个线程,他们可以利用进程所拥有的资源,操作系统中,通常把进程作为分配资源的基本单位,把线程作为独立运行和独立调度的基本单位,犹豫线程比进程更小,基本不用有系统资源。

一个进程至少需要一个线程作为它的指令执行体,进程管理着资源(比如CPU,内存,文件描述符等),线程将要分配到CPU上执行。

线程模型分为,核心级线程和用户级线程两种线程模型,分类的标准主要是线程的调度者是在内核内还是在外,前者更有利于并发使用多处理器的资源,后者更多考虑的是上下文切换开销。


linux内核只提供了轻量进程的支持,限制了更高效的线程模型的实现,但是linux着重

尽管linux支持轻量级进程,但并不能说,他就支持核心级进程,因为linux的线程和进程实际上处于一个调度层次,共享一个进程标识符空间,这种限制不可能在linux下实现完全意义上的POSIX线程机制。

linux内核并不支持真正意义上的线程,linuxthreads使用和普通进程具有同样内核调度视图的轻量级进程来实现线程支持的。这些轻量级进程拥有独立的进程ID,在进程调度,信号处理,IO等方面享有与普通进程一样的能力。

linux下的线程就是轻量级进程。

每个linuxthread线程都同时具有线程id和进程id,其中进程id就是内核所维护的进程号

,而线程id则由linuxthreads分配和维护

__pthread_initial_thread的线程id为PTHREAD_THREADS_MAX,__pthread_manager_thread的是2*PTHREAD_THREADS_MAX+1,第一个用户线程的线程id为PTHREAD_THREADS_MAX+2,此后第n个用户线程的线程id遵循以下公式:

tid=n*PTHREAD_THREADS_MAX+n+1

这种分配方式保证了进程中所有的线程(包括已经退出)都不会有相同的线程id,而线程id的类型pthread_t定义为无符号长整型(unsigned long int),也保证了有理由的运行时间内线程id不会重复。

从线程id查找线程数据结构是在pthread_handle()函数中完成的,实际上只是将线程号按PTHREAD_THREADS_MAX取模,得到的就是该线程在__pthread_handles中的索引。

5.线程的创建

在pthread_create()向管理线程发送REQ_CREATE请求之后,管理线程即调用pthread_handle_create()创建新线程。分配栈、设置thread属性后,以pthread_start_thread()为函数入口调用__clone()创建并启动新线程。pthread_start_thread()读取自身的进程id号存入线程描述结构中,并根据其中记录的调度方法配置调度。一切准备就绪后,再调用真正的线程执行函数,并在此函数返回后调用pthread_exit()清理现场。


linux下查看线程数的三种方法:

1. cat /proc/pid/status

2. pstree -p pid

3. top -H -p pid

4.ps xH,查看所有存在的线程

5.ps -mp pid

6.ps -eLf |grep


173825534.jpg

上面命令查询结果的第二列为PID,第三列为PPID,第四列为LWP,第六列为NLWP。





jstack 30420 | less,然后查找 nid=0x44bf,哦,找到了



Shell代码  收藏代码


  1. "main" prio=10 tid=0x0000000053911400 nid=0x44bf runnable [0x0000000040f5c000..0x0000000040f5ced0]  

  2.   java.lang.Thread.State: RUNNABLE  

  3.        at java.net.SocketInputStream.socketRead0(Native Method)  

  4.        at java.net.SocketInputStream.read(SocketInputStream.java:129)  

  5.        at java.net.SocketInputStream.read(SocketInputStream.java:182)  

  6.        at com.caucho.server.resin.Resin.waitForExit(Resin.java:524)  

  7.        at com.caucho.server.resin.Resin.main(Resin.java:614)  

 jstack 命令告一段落,先不研究了