初识线程之线程概念

我们之前学过进程,那么什么是线程呢?
在一个程序里的一个执行流被称作线程,线程是一个进程内部的控制序列。在Windows下,为线程分配一个线程控制块(TCB),管理起来比较复杂;而在Linux下,操作系统不区分线程和进程,均看作是进程,线程被称为轻量级进程(Light Weight)。我们之前理解的进程是只有一个PCB,可以看作是只有一个执行流的进程。现在引入线程的概念后,将其看作是具有多个执行流的进程。所以,一切进程至少有一个执行线程

在Linux下,进程是承担分配系统资源的实体,而线程是调度的基本单位。怎么理解这句话呢?想到进程,我们就应该联想到虚拟地址,并通过页表映射到物理地址空间的一连串东西,这些属于资源,而线程则是调度这些资源的,线程共享进程的数据,但也有自己的一部分数据。
初识线程之线程概念_第1张图片
那么多线程之间共享哪些资源呢?
1.堆
由于堆是在进程空间中开辟出来的,所以它是理所当然的被共享,因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)。
2.全局变量
全局变量与具体某一函数无关,所以与特定线程也无关,因此是共享的。
3.静态变量
存放在堆开辟的.bss和.data段,是共享的。
4.文件等公用资源
这个是共享的,使用这些公共资源的线程必须同步。Win32提供了几种同步资源的方式,包括:信号、临界区、事件和互斥体。

线程共享的环境
进程代码段、进程的公有数据、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID和进程组ID。

线程除了这些共享的部分,也有自己个性化的东西,包括:
1.线程ID(LWP)
每个线程都有自己的线程ID,是唯一的,进程用此来标识线程。
2.线程的私有栈
线程函数可以调用函数,而调用函数中可以层层嵌套,所以线程必须拥有自己的函数堆栈,使得函数调用可以正常执行,不受其他线程的影响。
3.独立的上下文
可以将上下文看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量、寄存器以及当时的环境。
4.错误返回码
由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用后设置了error值,而该线程还没有处理这个错误,另外一个线程就在此时被调度投入运行,这样错误值就有可能被修改。
5.信号屏蔽字
由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理。但所有的线程都共享同样的信号处理器。
6.线程优先级
由于线程需要像进程那样能够被调度,那么久必须要有可供调度使用的参数,这个参数就是线程的优先级。
7.寄存器组的值
由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线程切换到另一个线程上时,必须将原有的线程的寄存器集合的状态保存,以便将来在该线程在被重用切换到时能恢复。

线程的优点:
1.创建一个新线程比创建一个新进程代价小
2.线程之间的切换比进程之间的切换需要操作系统做的工作小的多
3.线程占用的资源比进程少
4.能充分利用多处理器的可并行数量
5.在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
6.计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
7.I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作

线程的缺点:
1.性能降低
增加了额外的同步和调度开销,而可用的资源不变。
2.健壮性降低
线程之间缺乏保护。
3.缺乏访问机制
进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。
4.编程难度高
编写与调试一个多线程的程序比单线程的程序困难得多

你可能感兴趣的:(Linux,线程)