互斥#########################
中断屏蔽***********************************
因为不能屏蔽其他CPU的中断,因此不能解决SMP多CPU引发的竞态,因为其他CPU也会引发竞争。
因此,单独使用中断屏蔽通常不是一种值得推荐的避免竞态的方法(换句话说,驱动中使用local_irq_disable/enable()通常意味着一个bug),它适合与下文将要介绍的自旋锁联合使用。
参考:https://blog.csdn.net/qq_40732350/article/details/83959180
原子变量和原子位操作***********************************
优点:简单
缺点:只能实现对变量这种资源进行互斥,不能对其他类型的资源进行互斥。
参考:https://blog.csdn.net/qq_40732350/article/details/83446184
自旋锁***********************************
自旋锁只有在内核可抢占或SMP(多处理器)的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。
不是说在单CPU且不可抢占的内核下不可以用自旋锁,而是在同一时间内,没有其他程序跟你竞争临界资源,就算使用了自旋锁也无意义。
参考:https://blog.csdn.net/qq_40732350/article/details/83049367
读写锁***********************************
顺序锁***********************************
读操作要读两次,如果两次相等就会就不会继续读,不相等就继续读。
参考:https://blog.csdn.net/qq_40732350/article/details/83959936
信号量***********************************
优点:可以睡眠
缺点:如果没有获得信号量,马上睡眠,从睡眠到唤醒的时间段过长,不适合等待时间较短的程序。
参考:https://www.cnblogs.com/shijingjing07/p/5615084.html
互斥量:
优点:可以睡眠
缺点:暂时先等待一小段时间,如果没有获得互斥量再睡眠,这样更高效。
RCU机制
优点:适合对链表的操作,适合读多写少
缺点:由于有宽限期,所以等待所有的读结束需要时间
参考:https://blog.csdn.net/qq_40732350/article/details/83996307
同步#########################
完成量:***********************************
适用于线程同步
参考:https://blog.csdn.net/qq_40732350/article/details/83117086
条件变量:***********************************
条件变量其实是用于实现生产者和消费者的问题
消费者线程启动,获取互斥量读缓冲区,发现为空,阻塞自己并同时释放互斥量;生产者线程启动,获取互斥量写缓冲区,写完毕后,通知消费者同时释放互斥量;消费者线程唤醒,获取互斥量读缓冲区;
参考:https://blog.csdn.net/qq_40732350/article/details/82720620
优点:可以实现生产者和消费者机制
缺点:要和互斥锁共同实现
应用层的同步总结:***********************************
互斥量:
优点:
1.适用于线程间的的读写会发生交互的情况
2.一旦互斥锁,上锁了,所有其他使用该锁的线程,都阻塞
缺点:
1.有可能发生死锁
2.锁解除了,不能及时通知其他线程
/*********************************************************************/
读写锁:
优点:
1.可以分读 锁和 写 锁,
2.可以用于,有些线程只读不写,或者只写不读的情况
3.可以最大效率的利用共享资源
缺点:
1.按照规则加上 读 锁后的线程,只应该进行 读 操作,但是我可以读也可以写,这回造成一些问题
2.读写锁会抛锚,有时能限制,有时不能限制,抛锚率 百分之三十
/*********************************************************************/
条件变量:
优点:
1.可以通知所有等待条件变量的线程,比互斥量效率高
2.完美解决了,互斥量要通过循环来判断,是否可以进行上锁操作,不浪费CPU
缺点:
1.需要互斥量结合,不能单独使用
参考:https://blog.csdn.net/qq_40732350/article/details/82720620
/*********************************************************************/
自旋锁:
优点:
1.可以一直判断锁的情况,可以及时的上锁
2.可以用在非常需要最开的到所得情况
缺点:
1.由于,没有得到自旋锁的进程会不断循环检测锁,因此上了锁的进程要以最快的速度做完事情,
2.这也就限制了,这种锁不应该用在占用时间的多的进程
3.反应太快,使得它不适用于进行全局变量的读和写
参考:https://blog.csdn.net/qq_40732350/article/details/82721154
/*********************************************************************/
屏障:
优点:
1.可以用于多个线程完成一个大的任务的情况
缺点:
1.只要一个线程没完成任务,其他线程都不能继续操作
参考:https://blog.csdn.net/qq_40732350/article/details/82723014
/*********************************************************************/
进程间通信#########################################
无名管道:
参考:https://blog.csdn.net/qq_40732350/article/details/82082115
有名管道:
参考:https://blog.csdn.net/qq_40732350/article/details/82082115
信号:
参考:https://blog.csdn.net/qq_40732350/article/details/82085250
消息队列:
参考:https://blog.csdn.net/qq_40732350/article/details/82844100
共享内存:
参考:https://blog.csdn.net/qq_40732350/article/details/82843187
信号量:
参考:https://blog.csdn.net/qq_40732350/article/details/82830013
套接字:
参考:
阻塞#########################################
参考我的博客:https://blog.csdn.net/qq_40732350/article/details/82823603
1.阻塞 I/O 模型:
在这种模型下, 若所调用的 I/O 函数没有完成相关的功能, 则会使进程挂起, 直到相关数据到达才会返回。 如常见对管道设备、 终端设备和网络设备进行读写时经常会出现这种情况。
2.非阻塞 I/O 模型:
在这种模型下, 当请求的 I/O 操作不能完成时, 则不让进程睡眠,而且立即返回。 非阻塞 I/O 使用户可以调用不会阻塞的 I/O 操作, 如 open()、 write()和 read()。 如果该操作不能完成, 则会立即返回出错(如打不开文件) 或者返回 0(如 在缓冲区中没有数据可以读取或者没空间可以写入数据)。 如何实现非阻塞IO访问: O_NONBLOCK: 只能在打开的时候设置 fcntl: 可以在文件打开后设置
3.I/O 多路复用模型:
在这种模型下, 如果请求的 I/O 操作阻塞, 且它不是真正阻塞I/O, 而是让其中的一个函数等待, 在此期间, I/O 还能进行其他操作。 外部表现为阻塞式,内部非阻塞式自动轮询多路阻塞式IO。其实内部就是while加非阻塞(类似),但是它内部不会占用CPU 太多时间。
优点:
不会浪费太多CPU时间,且达到while加非阻塞的效果
缺点:
1.select和poll本身是阻塞式的,当里面的条件没满足或者超时,就会一直阻塞,
2.这两个函数可以同时注册多个阻塞,但是只要有一个阻塞发生就会马上退出函数,而不会等其它阻塞发生,更不会等全部阻塞发生后才退出
4.信号驱动 I/O 模型:
在这种模型下, 进程要定义一个信号处理程序, 系统可以自动捕获特定信号的到来, 从而启动 I/O。 这是由内核通知用户何时可以启动一个 I/O操作决定的。它是非阻塞的。 当有就绪的数据时, 内核就向该进程发送 SIGIO 信号。 无论我们如何处理 SIGIO 信号, 这种模型的好处是当等待数据到达时, 可以不阻塞。 主程序继续执行,只有收到 SIGIO 信号时才去处理数据即可。
优点:快速,因为是内核进行处理
缺点:只能处理一种情况,因为只有一个信号
5.异步 I/O 模型:
在这种模型下, 进程先让内核启动 I/O 操作, 并在整个操作完成后通知该进程。 这种模型与信号驱动模型的主要区别在于: 信号驱动 I/O 是由内核通知我们何时可以启动一个 I/O 操作, 而异步 I/O 模型是由内核通知进程 I/O 操作何时完成的。 现在, 并不是所有的系统都支持这种模型。
6.特殊方式——轮询
不断对文件进行判断是否能使用,
优点:简单
缺点:浪费CPU时间