目录
5.内存地址空间 (.text/.data/.bss/heap/共享库)
线程的概念
轻量级的进程 ,一个进程内部可以有多个线程,默认情况下一个进程只有一个线程
线程就是轻量级的进程,如果说下图中的a.out,是一个进程,那里面的那几根"弯弯曲曲"的线,就是所谓的线程,一般来说,一个进程中只有一个线程,当然,一个进程中也可以有多个线程,这种状况就叫做多线程,当然从图上也可以看出来,一个进程中的多个线程,也是公用的相同的资源的:
因为线程是公用进程的空间的,那么可以理解为,在内存上,除了栈(stack)这块,其他地方都是共享的!(上图的左侧所示),这是因为线程是有自己的执行目的的,每个线程的任务是非常明确的,后面会提到,一个线程实际上就是执行的一个函数,因为函数是存储在栈中的,所以这块是没法共享的,要进行区分,除此之外,其他区域都是可以共享的。
线程的好处也就可以看出来了,线程都在一个进程内部,随便一个变量所有线程都可以用;线程可以更有效的理由CPU(但是,要说的是,如果电脑只有一块CPU,一个核心数,线程再多也没办法同时"干活儿",因为在一个进程中,只能有一个“线程”在运行的(可以把线程理解成一个函数)),总之,多线程和多进程,都是为了更充分的利用CPU。
那么再做个关于"进程"和"线程"的形象的比喻,一个工厂,但可供的电量有限,只能供应三个车间,错开开工,不能同时开工,那么这个工厂,就好比是cpu,这三个车间,可以理解成"进程",那么车间里面的每个人(苦力,真正干活的),就相当于"线程"。那么每个"线程"都有非常明确的分工。在车间里的设备和资源,对每个人(线程)来说也都是公有的。
线程是最小的执行单位,进程是最小的系统资源分配单位 ,从内核角度看,进程和线程是没有区分的,内核实现都是通过 clone 函数实现的,线程也有自己的PCB
线程共享资源
尽量不要让线程与信号放在一起使用,避免乱上加乱
1.文件描述符表
2.每种信号的处理方式
3.当前工作目录
4.用户ID和组ID
5.内存地址空间 (.text/.data/.bss/heap/共享库)
线程非共享资源
1.线程id
2.处理器现场和栈指针(内核栈)
3.独立的栈空间(用户空间栈)
4.errno变量(每个线程有自己独有的errno变量)
5.信号屏蔽字
6.调度优先级(可以设置线程的优先级)
线程的优缺点
优点
1. 提高程序并发性(为了更好的利用CPU) 2. 开销小(不必再申请空间,直接用的是进程的空间) 3. 数据通信、共享数据方便(在一个进程中的线程,可以共享进程中所创建的变量来共用)
缺点
1. 库函数,不稳定 (因为早期Unix并没有线程的概念,线程概念是后加的,所以,是放在了库函数中) 2. 调试、编写困难(可以让程序员后天学习克服) 3. 对信号支持不好(大不了就不用信号了)
汇总:优点相对突出,缺点均不是硬伤。Linux下由于实现方法导致进程、线程差别不是很大。