目录
一、库函数
系统调用和库函数的区别?
库函数的实现在库里,运行在用户态
系统调用的实现在内核中,编写内核时,已经实现,运行在内核态
二、进程间通讯
1.管道
管道 信号量 共享内存 消息队列 套接字
- 有名管道和无名管道的区别
有名在任意两个进程间通信 mkfifio/mkfif()
无名管道只能在父子进程间通信 pipi()
- 写管道的数据存放在哪里?
内存中
- 通信方式:半双工(单工 半双工 全双工) 广播 对讲机 电话
- 管道的实现
双指针 头指针负责写 尾指针负责读 头指针与尾指针的距离就是管道中的数据量
当读指针=尾指针+1 管道为空 当读指针=尾指针-1 管道为满
程序中有固定的读端和写端
若管道为空 读read阻塞 若管道为满 写write阻塞
操作管道时,要求读端和写端都存在
写端关闭,读read()直接返回,返回值为0
读端关闭,写write()产生异常,收到SIGPIPE信号(终止)
2.信号量 红绿灯
特殊的变量,原子减一(p操作,代表获取资源) 原子加一(v操作,代表释放资源)
信号量是用来同步进程
二值信号量 值取0或者1 资源能否被访问
计数信号量 值可以大于1 有多少的资源可被访问 类似试衣间 3间 即初始值为3
临界资源:同一时刻只允许一个(有限个)进程或线程访问的资源
临界区:访问临界资源的代码段
3.共享内存
Ipcs 查看进程间通信的讯号量 共享内存消息队列的使用情况
Ipcrm 删除
同步?
对临界资源的访问有控制,能保证同一时刻只有一个进程访问,则两个进程是同步的。
异步?
同步和异步的方式?
同步等结果 异步不等
同步和异步关注的是消息通信机制,所谓同步,就是在发出一个调用时,在没有得
到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是
由调用者主动等待这个调用的结果。
而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。
换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是等被调用者准
备好数据后反过来通知调用者。
同步在不同地方,意义不同
阻塞与非阻塞
阻塞? 条件不满足,挂起 非阻塞? 条件不满足,返回失败
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。阻塞是指
方法(函数)执行后,在结果返回之前,当前线程(进程)会被挂起。调用线程(进程)
只有在得到结果之后才会返回。
非阻塞方法(函数)指在不能立刻得到结果之前,该方法(函数)不会阻塞当前线
程,可以立即返回,只是返回结果是失败,没有数据,一般需要 cpu 周期性轮询,以检
查数据是否就绪。
4.消息队列
类似于的缓冲大
线程于进程的区别?
进程是一个正在运行的程序,是系统进程资源分配的基本单位
线程是进程内部的一条执行路径,是系统调度的基本单位
理解多线程的并发运行
三、线程同步的方法:
信号量 互斥锁 读写锁 条件变量
信号量和互斥锁的区别?
互斥锁相当于一个初始值为1的二值信号量 在这种条件等价,可互换
互斥锁是信号量的子集 主要完成互斥性问题
自旋锁 内核中同步使用的,用户空间中没有 需要多处理器
忙等待的锁? 等待时间<切换时间 会一直占用cpu 进行测试 直至条件满足
非忙等待的锁?阻塞 挂起
CAS
原子操作?怎么实现的?
《从哲学层次看操作系统》 -----锁的实现 1.禁止/开启 中断 2测试与设置特殊指令
线程的实现?
操作系统关于线程的实现:用户级线程 内核级线程 组合形式
时间片轮转 并发(多处理器 线程开销小)
用户级:线程创建 管理 销毁,都由线程库代码完成,开销比较小
内核级:线程创建,管理都由内核完成,开销小
用户级无法使用多处理器资源,内核级可以(用户不知道有多少线程)
Linux线程的实现
《linux内核设计与实现》第三版
查看线程Id:ps -eLf L 显示线程信息 f显示其他信息 e 显示路径
top -H 打印系统使用的cpu id, f+j 查看多个线程信息
生产者消费者
信号量 互斥锁 进行同步 《操作系统精髓与设计原理》第5版
让两个线程交替打印 “ababababab”
将共享内存的一个写进程换为print a 另一个读进程换为print b
信号量 两个 a b c交替打印
线程安全
Printf是不是线程安全
不是
什么是线程安全
执行的逻辑正确 安全
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护, 其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据