1.进程线程区别:
1.从本质上区分:
进程是操作系统资源分配的基本单位
线程是任务调度和执行的基本单位
2.在开销方面:
每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销
线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小
3.稳定性方面:
进程中某个线程如果崩溃了,可能会导致整个进程都崩溃。而进程中的子进程崩溃,并不会影响其他进程。
4.内存分配方面:
系统在运行的时候会为每个进程分配不同的内存空间
而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源
5.包含关系:
没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的
线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程
2.进程,线程,PUB,内核结构 之间的微妙关系
进程和线程都是PCB结构体(轻量级进程)描述的
3.CPU与线程之间的关系
并发是指一个处理器同时处理多个任务。
并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。1.一个线程执行需要占用一个CPU资源
2.多个CPU执行多个线程可以分配不同的线程给多个CPU执行,这样就是并行的角度;多个线程可以轮换的使用一个CPU进行执行,这样就是并发
3.并发就考虑到线程之间的分配机制,请看Linux内核设计与实现
4.线程切换的理论
CPU切换线程
PCB结构体中存储了很多信息,而这些信息就是用于恢复线程在CPU中执行的位置,其中包括PC指针和寄存器的值
1.PC指针指向下一条执行函数的命令
2.寄存器信息保存为当前线程运行的所有数据
3.以及PUC结构体的其他信息保证线程基本设置与之前一致
6.线程与子进程的详细区别
1.从系统角度而言,Linux中的线程与子进程的描述都是通过PCB结构体(也就是轻量级进程)表示的,只不过对于二者之间的信息有所不同,二者的不同体现在实现上
2.那么从实现角度上看
3.子线程的优势:
子线程切换更方便,因为多数资源是与进程共享的,本质也就提高了运行效率
并行执行,高效发挥多核CPU的优势提高了运行效率
适用于大量计算的场景,多用于计算密集型程序
4.多线程的劣势
多线程不会因为线程的加多无限提高效率,效率呈现正态分布.因为线程过多后会出现线程切换频繁影响效率的问题
多线程的健壮性不高
临界资源会出现二义性的问题,需要加锁保护
线程加锁可能会出现线程饥饿的问题,还需要考虑线程同步的问题,满足线程互斥的情况下需要一个处理临界资源更合理的方法
5.线程的独有和共享
7.各种锁解决同步问题
锁的种类
读锁 : 只可对数据进行查看而不能修改的锁,期间可以加读锁后进行访问数据,可同时多线程访问.期间不能加写锁
写锁 : 期间不能加任何锁,释放后才能访问,可对数据进行修改
互斥锁 : 标记的临界资源只能在此期间被一个线程访问
悲观锁 : 每次修改数据都认为别人回来抢资源,所以在操作之前先上锁
乐观锁 : 每次修改数据都认为别人不会抢资源,所以在操作之前不上锁,但是在更新前会判断一下这个数据是否被修改过 (例如版本号) - 读多写少
自旋锁:当一个线程尝试去获取某一把锁的时候,如果这个锁此时已经被别人获取(占用),那么此线程就无法获取到这把锁,该线程将会等待,间隔一段时间后会再次尝试获取。
死锁现象
互斥条件:
临界资源是独占资源,进程应互斥且排他的使用这些资源。占有和等待条件:
进程在请求资源得不到满足而等待时,不释放已占有资源。不剥夺条件:
又称不可抢占,已获资源只能由进程自愿释放,不允许被其他进程剥夺。循环等待条件:
又称环路条件,存在循环等待链,其中,每个进程都在等待链中等待下一个进程所持有的资源,造成这组进程处于永远等待状态。提高互斥锁使用效率
互斥锁和条件变量要一起使用
1.互斥锁:主要是用在多线程编程时,多个线程同时访问同一个变量的情况下,保证在某一个时刻只能有一个线程访问。
2.条件变量:作用是用于多线程之间的线程同步。线程同步是指线程间需要按照预定的先后顺序进行的行为,比如我想要线程1完成了某个步骤之后,才允许线程2开始工作,这个时候就可以使用条件变量来达到目的。