[1]进程
1.每创建一个进程,内核都会给这个进程分配资源(内存.cpu...)。
2.进程是系统分配资源的最小单位。
3.进程之间,彼此的地址空间是独立的(每个进程都有自己独立的虚拟地址空间)
[2]线程
1.同一个进程的多个线程共享一份全局内存区域(多个线程同属于同一个进程)
2.线程是系统调度的最小单位
3.线程是轻量级的进程(因为每个线程都存在一个进程描述符task_struct)
[3]线程和进程的关系
[4]为什么需要多线程
1.好比去银行办理业务,你一定希望,办理业务的窗口越多越好。如果把整个营业大厅当成一个进程的话,那么每一个窗口就是一个工作线程。
2.Master-worker并发模型
--------------------------------------------------------------------------------
Master线程→创建线程 [请求] [请求] [请求]... // 排队等待区
↓
worker线程 [请求]
↓
worker线程 [请求]
↓
worker线程 [请求]
--------------------------------------------------------------------------------
[5]多线程共享资源带来的优势
1.创建线程花费的时间要少于创建进程。
2.终止线程花费的时间要少于终止进程。
3.线程之间上下文切换的开销,要小于进程之间的上下文切换 。// 上下文: 不同线程/进程之间
4.线程之间数据的共享比进程之间的共享要简单。
5.线程之间通信的代价低于进程之间通信的代价。 //部门内的协作总是要比跨部门的协作来得顺溜
6.发挥多核优势,充分利用CPU资源 // 单进程的排队模式可能导致CPU资源浪费,而任务还不能快速处理
7.更自然的编程模型:将工作切分成多个模块,并为每个模块分配一个或多个执行单元。
[6]多线程的缺点
1.要有一个线程不够健壮存在bug,就会导致进程内的所有线程一起完蛋。
2.线程模型作为一种并发的编程模型,效率并没有想象的那么高,会出现复杂度高、易出错、难以测试和定位的问题
3.多个线程之间需要同步:
·比如: 一个公寓,当你朋友正在使用卫生间的时候,你就无法使用了。
·若存在多个线程操作共享资源,则需要同步,否则可能会出现结果错误、数据结构遭到破坏甚至是程序崩溃等后果。
·因此多线程编程中存在临界区的概念,临界区的代码只允许一个线程执行,线程提供了锁机制来保护临界区。
·当其他线程来到临界区却无法申请到锁时,就可能陷入阻塞,不再处于可执行状态,线程可能不得不让出 CPU 资源。
4.多线程的四大陷阱
· 死锁(Dead Lock)
· 饿死(Starvation)
· 活锁(Live Lock)
· 竞态条件(Race Condition)
[7]总结
多进程属于立体交通系统,虽然造价高,上坡下坡比较耗油,但是堵车少;
多线程属于平面交通系统,造价低,但是红绿灯太多,老堵车。
立体: 进程间地址空间互相独立
造价高: fork后copy父进程资源
耗油: 通行前创建: 管道.FIFO.共享内存.消息队列.信号量
堵车少: 通信顺畅, 不受其他进程影响
平面: 多个线程共享该进程所有资源
造价低: 不用去拷贝资源, 仅共享
灯太多: 各种锁, 访问控制
老堵车: 多个资源抢夺锁去访问临界资源, 难获得锁。