Linux线程理论

线程是操作系统能够调度和执行的基本单位,在Linux中也被称之为轻量级进程。线程只是一个与其他进程共享某些资源的进程。每一个线程拥有一个唯一的task_struct结构,Linux内核它仅仅把线程当做一个正常的进程,或者说是轻量级进程,LWP(Lightweight processes)。


线程与进程的区别

Linux线程与进程的区别,主要体现在资源共享、调度、性能几个方面。

资源共享区别

线程其实是共享了某一个进程的资源,这些资源包括:

  • 内存地址空间
  • 进程基础信息
  • 大部分数据
  • 打开的文件
  • 信号处理
  • 当前工作目录
  • 用户和用户组属性
  • 等等

哪些是线程独自拥有的呢?

  • 线程ID
  • 一系列的寄存器
  • 栈的局部变量和返回地址
  • 错误码 errno
  • 信号掩码
  • 优先级
  • 等等

线程拥有独立的调用栈,除了栈之外共享了其他所有的段segment。但是由于线程间共享了内存,也就是说一个线程,理论上是可以访问到其他线程的调用栈的,可以用一个指针变量,去访问其他线程的局部栈帧,以访问其他线程的局部变量。

调度区别

说到调度,就得提到进程的上下文切换。上下文切换也被称作为进程调度或者任务切换,简单的来说是把CPU从一个进程或者线程切换到另一个执行。概括的来说,线程的上下文切换,要比进程更加快速,因为本质上,线程很多资源都是共享进程的,所以切换时,需要保存和切换的项是很少的。

线程上线文切换时,虚拟地址空间是不变的,但是进程上下文切换时,是需要重新映射虚拟地址空间。进程切换上下文时,进出OS内核&寄存器切换,是最大的时间支出。更模糊的代价是上下文切换时,会干扰处理器的缓存机制。当上下文切换时,处理器需要重新cache一些内存。

这里更大的一个区别时,当更改虚拟地址空间时,CPU 的 TLB 等也会被刷新,导致接下来的内存访问更加耗时,所以相对线程切换来说,进程的切换耗时更大。

CPU切换原理文章:

罗政:CPU上下文切换原理

性能区别

从性能方面,来查看一下线程与进程的对比。由于线程更加轻量,导致线程的创建速度、切换速度都要高于进程。

线程缺点

线程同样也有缺点,最大的缺点是线程的不安全性,缺乏保护机制。就是上面提到的黑科技,因为线程间共享数据,一个线程可以重写另外一个线程的堆栈,导致出现一些异常的情况。除此之外,线程还有以下缺点:

  • 共享属性:全局变量是在所有线程间共享的,访问时是需要同步加锁。
  • 很多库函数是线程非安全的,多线程编程时,需要注意这一点。
  • 线程的健壮性不强,如果一个线程crash了,那么整个应用程序就跪了。


查看linux系统java进程的所有线程情况:

top -Hp 进程PID

[root@VM-0-3-centos ~]# top -Hp 18457
top - 09:53:58 up 19 days, 17:50,  1 user,  load average: 0.06, 0.05, 0.05
Threads:  52 total,   0 running,  52 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.2 sy,  0.0 ni, 99.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3880184 total,   175632 free,   709012 used,  2995540 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  2887792 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                              
18479 root      20   0 1399536 340752   7544 S  0.3  8.8  65:17.14 java                                                                                                                 
18457 root      20   0 1399536 340752   7544 S  0.0  8.8   0:00.00 java                                                                                                                 
18458 root      20   0 1399536 340752   7544 S  0.0  8.8   0:07.73 java                                                                                                                 
18459 root      20   0 1399536 340752   7544 S  0.0  8.8   0:05.73 java                                                                                                                 
18460 root      20   0 1399536 340752   7544 S  0.0  8.8   0:05.71 java                                                                                                                 
18461 root      20   0 1399536 340752   7544 S  0.0  8.8   0:52.09 java                                                                                                                 
18462 root      20   0 1399536 340752   7544 S  0.0  8.8   0:00.62 java                                                                                                                 
18463 root      20   0 1399536 340752   7544 S  0.0  8.8   0:01.51 java                                                                                                                 
18464 root      20   0 1399536 340752   7544 S  0.0  8.8   0:00.00 java                                                                                                                 
18465 root      20   0 1399536 340752   7544 S  0.0  8.8   0:51.32 java                                                                                                                 
18466 root      20   0 1399536 340752   7544 S  0.0  8.8   0:10.85 java                                                                                                                 
18467 root      20   0 1399536 340752   7544 S  0.0  8.8   0:00.00 java                                                                                                                 
18468 root      20   0 1399536 340752   7544 S  0.0  8.8  13:23.91 java                                                                                                                 
18477 root      20   0 1399536 340752   7544 S  0.0  8.8   0:27.22 java                                                                                                                 
18478 root      20   0 1399536 340752   7544 S  0.0  8.8   0:09.50 java                                                                                                                 
18481 root      20   0 1399536 340752   7544 S  0.0  8.8   0:25.63 java                                                                                                                 
18489 root      20   0 1399536 340752   7544 S  0.0  8.8   1:03.76 java

支付宝打赏 微信打赏

如果文章对您有帮助,您可以鼓励一下作者