简述互斥锁的机制,互斥锁与读写的区别?⭐⭐⭐⭐⭐
简述自旋锁和互斥锁的使用场景⭐⭐⭐⭐⭐
公平锁与非公平锁⭐⭐⭐⭐⭐
死锁与活锁⭐⭐⭐⭐⭐
说说sleep和wait的区别?⭐⭐⭐
请介绍一下5种IO模型⭐⭐⭐⭐⭐
简述同步与异步的区别,阻塞与非阻塞的区别?⭐⭐⭐⭐⭐
BIO、NIO有什么区别?⭐⭐⭐⭐⭐
说说多路IO复用技术有哪些,区别是什么?⭐⭐⭐⭐⭐
说说epoll的原理⭐⭐⭐⭐⭐
简述epoll和select的区别,epoll为什么高效?⭐⭐⭐⭐⭐
epoll水平触发与边缘触发的区别?⭐⭐⭐⭐⭐
=========================================================================================================
- 本专栏适合于C/C++已经入门的学生或人士,有一定的编程基础。
- 本专栏适合于互联网C++软件开发、嵌入式软件求职的学生或人士。
- 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。这才是一份面试题总结的正确打开方式。这样才方便背诵
- 针对于非科班同学,建议学习本人专刊文章《蒋豆芽的秋招打怪之旅》,该专刊文章对每一个知识点进行了详细解析。
- 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
- 相信大家都有着高尚的灵魂,请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。
=========================================================================================================
简述互斥锁的机制,互斥锁与读写的区别?⭐⭐⭐⭐⭐
互斥锁机制:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时,线程会进入阻塞,等待锁释放。
互斥锁和读写锁:
(1) 读写锁区分读者和写者,而互斥锁不区分
(2)互斥锁同一时间只允许一个线程访问该对象,无论读写;读写锁同一时间内只允许一个写者,但是允许多个读者同时读对象。
简述自旋锁和互斥锁的使用场景⭐⭐⭐⭐⭐
- 互斥锁用于临界区持锁时间比较长的操作,比如下面这些情况都可以考虑
(1)临界区有IO操作
(2)临界区代码复杂或者循环量大
(3)临界区竞争非常激烈
(4)单核处理器
- 自旋锁就主要用在临界区持锁时间非常短且CPU资源不紧张的情况下。
公平锁与非公平锁⭐⭐⭐⭐⭐
公平锁:就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己
非公平锁:非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式。
非公平锁的优点在于吞吐量比公平锁大。死锁与活锁⭐⭐⭐⭐⭐
死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
活锁:是指线程1可以使用资源,但它很礼貌,让其他线程先使用资源,线程2也可以使用资源,但它很绅士,也让其他线程先使用资源。这样你让我,我让你,最后两个线程都无法使用资源。说说sleep和wait的区别?⭐⭐⭐
(1)sleep是一个延时函数,让进程或线程进入休眠。休眠完毕后继续运行。
(2)wait是父进程回收子进程PCB(Process Control Block)资源的一个系统调用。
请介绍一下5种IO模型⭐⭐⭐⭐⭐
IO(Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作。
通常用户进程中的一个完整IO分为两阶段:用户进程空间与内核空间之间的相互切换、内核空间与设备空间的相互切换(磁盘、网络等)。我们通常说的IO是指网络IO和磁盘IO两种。
Linux中进程无法直接操作I/O设备,其必须通过系统调用请求内核来协助完成I/O动作;内核会为每个I/O设备维护一个缓冲区。
对于一个输入操作来说,进程IO系统调用后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备中读取,因为设备IO一般速度较慢,需要等待;内核缓冲区有数据则直接复制到进程空间。
所以,对于一个网络输入操作通常包括两个不同阶段:- 等待网络数据到达网卡→读取到内核缓冲区,数据准备好;
- 从内核缓冲区复制数据到进程空间。
5种IO模型如下:
- 阻塞IO:进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程。操作成功则进程获取到数据。调用者将一直等待,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
- 非阻塞IO:进程发起IO系统调用后,进程被阻塞,内核数据还没好,不想让进程等待,就返回一个错误,这样进程就不阻塞了。进程每隔一段时间就发起IO系统调用去检查IO事件是否就绪。这样就实现非阻塞了。每个进程都有一个时间片,轮询的时候读取IO,时间片到了就要换另一个进程做其他事情了,这样就做到了每隔一段时间发起IO系统调用。
- IO多路复用:Linux用select/poll函数实现IO复用模型,这两个函数也会使进程阻塞,但是和阻塞IO所不同的是这两个函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检查。select/poll会监听所有的IO,直到有数据可读或可写时,才真正调用IO操作函数。
- 信号驱动IO:Linux用套接口进行信号驱动IO,安装一个信号处理函数,进程继续运行并不阻塞,当IO事件就绪,进程收到SIGIO信号,然后处理IO事件。这个好理解,这个信号直接通知进程数据到了。
- 异步IO:进程发起IO系统调用后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。用户可以直接去使用数据。具体操作是进程调用aio_read函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回。
前四种属于同步IO,原因就在于进程发起IO系统调用读取数据时,这个真正拿到数据的过程依然是阻塞的,直到完成数据读取还要把数据拷贝到用户空间中,进程才能继续做其他事。
而异步IO就不一样了,进程完全做自己的事情,数据都不需要它读取,而是由内核读取数据并将数据拷贝到缓冲区后,再通知应用程序。用户可以直接去使用数据。简述同步与异步的区别,阻塞与非阻塞的区别?⭐⭐⭐⭐⭐
同步与异步的区别:
同步:所有的操作都做完,才返回给用户结果。即写完数据库之后,再响应用户,用户体验不好。双方的动作是经过双方协调的,步调一致的。
异步:不用等所有操作都做完,就响应用户请求。即先响应用户请求,然后慢慢去写数据库,用户体验较好。双方并不需要协调,都可以随意进行各自的操作。
阻塞与非阻塞的区别:
阻塞:调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
非阻塞:非阻塞等待,每隔一段时间就去检查IO事件是否就绪。没有就绪就可以做其他事情。
BIO、NIO有什么区别?⭐⭐⭐⭐⭐
BIO、NIO的区别:
BIO(Blocking I/O):阻塞IO。进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程。操作成功则进程获取到数据。调用者将一直等待,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
NIO(New I/O):同时支持阻塞与非阻塞模式,NIO的做法是叫一个线程不断的轮询每个IO的状态,看看是否有IO的状态发生了改变,从而进行下一步的操作。
说说多路IO复用技术有哪些,区别是什么?⭐⭐⭐⭐⭐
select,poll,epoll都是IO多路复用的机制,I/O多路复用就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪(一般是读就绪或者写就绪),能够通知应用程序进行相应的读写操作。
区别:
(1)poll与select不同,通过一个pollfd数组向内核传递需要关注的事件,故没有