1. 互斥锁使用的时候注意的问题
临界区:lock和unlock中间的代码就叫做临界区,在上锁时应该保证临界区越小越好。
在上锁时应该保证临界区越小越好:
2. 线程为什么要加锁
先说一下什么是原子操作:
通过加锁的方式来模拟原子操作:下图中lock和unlock中间的三行代码,如果不加锁时,这三行代码在执行中可能会失去CPU,所以不是原子操作,而加上锁之后,其他线程会阻塞等待,不会抢走时间片,所以这三行代码会一气呵成执行完毕,因此用加锁的方式可以用来模拟原子操作。
3. 死锁
如果两个或两个以上的线程都阻塞了,若无外力作用,他们将无法推进下去,这些线程会一直互相等待,这种现象称为死锁。
注:上面代码会阻塞在第二个lock处。
注:让线程按照一定的顺序去访问共享资源,就是说所有的线程都以同样的顺序去访问共享资源,都是先访问A,再访问B。这样就不会出现死锁了。
4. 读写锁的特性
5. 读写锁的使用场景
6. 读写锁操作函数
7. 读写锁练习代码
(1)当不加锁时:
执行结果:可以看到出现了数据混乱的情况
(2)当加锁时:
执行结果:数是由小到大的,没有出现数据混乱
8. 条件变量的使用思路
注:烧饼就是链表的节点,生产者采用头插法将节点插入链表。
9. 条件变量相关函数介绍
注:限时等待一个条件变量,就是当传入的参数abstime的时间到了之后,如果此时线程仍未解除阻塞,那么线程就会解除阻塞。
10. 生产者和消费者模型代码实现
生产者一直在头部插入节点。消费者一直将链表的头节点删除(当链表的头节点不为NULL时)。
11. 使用条件变量实现生产者消费者模型
执行结果:
12. 信号量相关的函数
13. 信号量实现生产者消费者模型
14. 信号量实现生产者消费者模型代码
15. 哲学家就餐问题分析