一、线程的概念(复习)-铺垫
进程是分配系统资源的基本单位
线程是一个标准的进程(一个执行流的进程)
- Linux线程图解
1.理解(Linux平台)
线程是在进程的内部运行的:线程是在进程的地址空间
内运行的,共享一份虚拟地址空间。
线程大部分资源都是共享的。(共用一个虚拟地址空间)
进程大部分资源都是独立的。(每个一个进程都有自己独自的一份虚拟地址空间)
CPU是只能识别PCB的,但是他无法区分进程还是线程。所以Linux当中CPU看到的一个线程相当于一个轻量级进程(<=一个标准的进程(一个执行流的进程))
Linux下没有一份真正意义的进程。使用进程模拟线程。
TCB ThreadContrlClock 线程控制块
- 线程概念
2.线程的资源
- 私有资源
线程ID
一组寄存器(上下文保护)
线程栈
erro
信号屏蔽字
调度优先级
- 共享资源
同有个地址空间
文件描述符
每种处理信号处理方式(忽略,默认,自定义)
当前工作目录
用户id和组id
3.线程优点
创建线程比创建一个进程代价小
与进程之间切换相比,线程之间的切换需要操作系统的工作小的多
线程占用的资源要比进程少很多
能充分利用多处理器的可并行数量
在等待慢速IO操作的同时,程序可以执行其他任务
计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
IO密集型应用,为了提高性能,将IO操作重叠。线程可以同时等待不同IO操作
4.线程缺点
性能损失
一个很少被外部事件阻塞的计算密集型线程往往⽆无法与共它线程共享同⼀一个处理器。如 果计算密集型线程的数量⽐比可⽤用的处理器多,那么可能会有较⼤大的性能损失,这⾥里的性 能损失指的是增加了额外的同步和调度开销,⽽而可⽤用的资源不变。
健壮性降低
编写多 程需要更全⾯面更深⼊入的考虑,在一个多线程程序⾥里,因时间分配上的细微偏差 或者因共享了不该共享的变量⽽而造成不良影响的可能性是很⼤大的,换句话说线程之间是 缺乏保护的。
缺乏访问控制
进程是访问控制的基本粒度,在⼀一个线程中调⽤用某些OS函数会对整个进程造成影响
编程难度提高
二、Linux线程ID和进程ID
在Linux查看正在运行的线程
ps -aL
-
线程ID和进程ID
同一个进程内部的线程(多个执行流)用getpid()返回的是一个一个PID。(用户级id) -
一个进程里面对应多个PCB(线程的PCB)
LWP - getttid() –pid (操作系统级别)
-
ps命令中的-L选项,会显示如下信息:
LWP
:线程ID,既gettid()系统调用的返回值。
NLWP
:线程组内线程的个Linux提供了gettid系统调用来返回其线程ID,可是glibc并没有将该系统调用封装起来,在开放接口来共程序员使 用。如果确实需要获得线程ID,可以采用如下方法:
#include <sys/syscall.h> pid_t tid; tid = syscall(SYS_gettid);
当一个线程的pid=tgid则这个线程是主线程
-
线程ID及进程地址空间布局
pthread_create
函数会产生一个线程ID,存放在第一个参数指向的地址中。该线程ID(库级别操作id)和前面所说的线程ID(pid)不是一回事。
前面讲的线程ID属于进程调度的范畴
。因为线程是轻量级进程,是操作系统调度器的最小单位
,所以需要 一个数值
来唯一表示该线程。
pthread_ create函数第一个参数指向一个虚拟内存单元
,该内存单元的地址即为新创建线程的线程ID
,属于 NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。 线程库NPTL提供了pthread_ self函数
,可以获得线程自身的ID:
pthread_t pthread_self(void);