系统
2020-07-19 本文已影响0人
谭英智
锁
互斥锁
加锁如果已经有其他线程加锁了,则阻塞,如果有多个线程在等待锁的释放,在锁释放的时候,所有线程都会被唤醒并置为就绪状态,第一个变成就绪的线程又执行加锁,其他线程又会进入等待
自旋锁
不会阻塞,使用死循环在内存检测锁是否已经释放
读锁
例如一个链表,在一个线程读的时候,当然不允许其他线程写入链表
写锁
对于一个数据结构,只允许一个线程写入
递归锁
死锁
- 按顺序加锁
- 如果一个线程无法在指定时间内获得锁,则结束当前线程业务,释放所有的锁资源
- 死锁检测
- 银行家算法
协程/线程/进程
协程
用户态的线程,切换由用户态管理,不需要经过内核
优点
- 无须线程上下文切换的开销
- 无须原子操作及同步的开销
- 方便切换控制流
缺点
- 无法利用多核优势
- 进程阻塞会阻塞整个程序
线程
优点
- 消耗资源比进程少
- 共享内存
缺点
- 内存共享,使用共用地址空间,内存受限
- 同步和加锁比较麻烦
- 一个线程崩溃会影响整个程序的稳定性
- 到达一定线程数后,再增加无法提高CPU的使用性能
- 线程多,调度会消耗大量CPU资源
进程
优点
- 每个进程独立,一个进程崩溃,不会影响其他进程
- 减少线程加锁的影响
缺点
- 需要跨进程交互,大量数据拷贝,导致开销大
进程间通讯
无名管道
优点
- 简单方便
缺点
- 局限于单向通讯
- 只能创建在它的进程以及其有亲缘关系的进程之间
- 缓存区有限
有名管道
优点
- 任意关系的进程间通讯
缺点:
- 单向通讯
- 长期存在于系统,使用不当会出错
- 缓冲区有限
消息队列
优点
- 任意进程通讯
- 系统调用实现消息发送和接受的同步,无需考虑同步问题
缺点
- 系统调用消耗CPU
- 复制信息消耗CPU
- 不适于信息量大,操作频繁的场合
信号
优点
- 通知方便
缺点
- 信息量少
socket
优点
- 可以跨机器
缺点
- 开销大,需要通过网络
共享内存
优点
- 无需多次复制,快
缺点
- 读写需要考虑同步问题
- 只能在一台机器共享
守护进程
operactionsystem-process- 创建子进程,父进程退出
脱离终端,shell终端可以执行其他命令
原理:父进程先于子进程退出,造成子进程成为孤儿进程,系统发现此孤儿进程,会把此进程收养到init进程下(1进程)
- 子进程创建会话,使用setid()--进程组/会话期
进程组:是一个或多个进程的集合。进程组有进程组ID来唯一标识。除了进程号(PID)之外,进程组ID也是一个进程的必备属性。每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID。且该进程组ID不会因组长进程的退出而受到影响
会话周期:会话期是一个或多个进程组的集合。通常,一个会话开始与用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。
setsid函数作用:setsid函数用于创建一个新的会话,并担任该会话组的组长。摆脱原会话/进程组/控制终端的控制
- 再次fork子进程,父进程退出
由于上一部进程成为了一个新的会话的组长,会话组长是可以申请打开一个控制终端,通过再次fork子进程,父进程退出,会让子进程变成不是会话组长,将不能申请控制终端。
- 改变当前目录为根目录
fork创建的子进程会继承父进程的当前工作目录,这回导致此工作目录不可卸载,所以需要把当前目录更改为根目录
- 重设文件权限掩码:umask(0)
fork的自己成会继承父进程的文件掩码,为了加大子进程的灵活性,最好把掩码设为0
- 关闭文件描述符
fork的子进程会继承父进程的文件描述符,而这些文件描述符子进程永远也不会使用,如果不关掉,会造成资源浪费