当我们去面试的时分,问到了 redis,nginx,netty他们的底层模型辨别是什么?
redis -> epoll
nginx-> epoll
netty-> epoll?
需求从操作系统的层面下去谈
BIO当我们开机的时分,首先被加载进内存的是我们的Kernel(内核),内核是用于管理我们的硬件的,同时内核还会创立一个GDT表,然后划分两个空间(用户空间和内核空间),同时空间中的内容是开启了保护形式,无法被修正的。
同时还有一个CPU的概念,CPU有本人的指令集,并且指令集是分了几个级别的,辨别是从0~3的,Kernel属于0级别。APP只能用级别为3的指令集。
从下面我们可以知道,我们的运用顺序是无法直接拜访我们的Kernel的,也就是顺序不能直接拜访我们的磁盘,声卡,网卡等设备,只要内核才可以拜访,那我们怎样办?
只要APP经过调用Kernel提供的 syscall(系统软中缀和硬中缀)来获取硬件中的内容。
软中缀硬中缀:硬中缀指的是我们的键盘,按下一个按键的时分,就会触发我们的硬中缀,也就是内核会有一个中缀号,然后失掉一个callback的回调函数
说到这里,其实就是为了引出一个 概念,就是 IO 和 内核之间的成本成绩
/**
* 效劳器读取文件
* @author: 陌溪
* @create: 2020-07-01-20:40
*/
public class TestSocket {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8090);
System.out.println("step1: new ServerSocket(8090)");
while(true) {
Socket client = server.accept();
System.out.println("step2: client " + client.getPort());
new Thread(() -> {
try {
InputStream in = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
while(true) {
System.out.println(reader.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}, "t1").start();
}
}
}
抓取顺序对内核有没有系统调用,然后输入
strace -ff -o ./ooxx java TestSocket
然后我们执行下面的顺序,失掉我们的结果
然后我们在经过jps命令,查看以后TestSocket的进程号
jps
2912 Jps
2878 TestSocket
然后我们在进入下面的这个目录下,启动2878是线程的id号,这个目录就是寄存该线程的一些信息
cd /proc/2878
我们可以看到2878进程下的,经过查看task目录,可以看到一切线程数
还有一个目录,就是 fd目录,在该目录下,就是我们的一些IO流
下面的0,1,2,辨别对应着 输入流,输入流和错误流。在java外面我们流就是对象,而在linux系统中,流就是一个个的文件。前面的4,5 就对应着我们的socket通讯,辨别对应着ipv4 和 ipv6
经过netstat命令查看
然后我们运用nc衔接 8090端口
nc localhost 8090
我们执行完后,经过netstat命令查看 ,发现多了个衔接的形状
然后在看文件外面,也多了一个socket
我们查看系统调用,发现经过系统调用接纳了一个58181端口号的央求,在前面我们还可以看到5,这个5其实就是对应的上图外面的socket,走的是ipv4。
从这里其实我们就可以知道了,我们原来调用中写的代码
Socket client = server.accept();
对应到系统层面,也是调用了系统的办法。
同时关于系统调用,有以下几种方式
bind
connect
listen
select
socket
(责任编辑:admin)