美文网首页
什么是epoll

什么是epoll

作者: momdiemg | 来源:发表于2020-06-15 15:11 被阅读0次

在linux执行这一段代码,跟踪他他看信息,查看生命周期

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;


public class IoTest {
    public static void main(String args[])throws IOException {
        ServerSocket server = new ServerSocket(8090);
        System.out.println("step1: new ServerSocket(8090) ");

        while (true) {
            Socket socket = server.accept();
            System.out.println("step2: client\t"+socket.getPort());
            new Thread(()->{
                try {
                    InputStream is = socket.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    while (true) {
                        System.out.println("is: "+reader.readLine());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }).start();
        }
    }
}

终端1


/**
 *
 *
 * strace 跟踪
 * -ff 克隆 fork进程
 * -o 输出
 *./ooxx 指定文件
 *
 *java 监视进程
 *./Myproject/io/IoTest 指定class文件
 *
 *
 *
 */
[root@localhost io]# strace -ff -o ./xxoo java IoTest
step1: new ServerSocket(8090) 



终端2

[root@localhost io]# javac IoTest.java 
[root@localhost io]# ll
总用量 8
-rw-r--r--. 1 root root 1986 6月  15 10:16 IoTest.class
-rw-r--r--. 1 root root  887 6月  15 10:16 IoTest.java
[root@localhost io]# java IoTest
image.png

追踪IoTest的class文件


image.png image.png

追踪到系统调用,然后进去,再第2554行找到了


image.png
image.png

打开第三个终端,追踪线程


image.png
task表示进程里面的所有线程文件
image.png
fd表示文件描述符
任何文件都有io

0:输入
1:输出
2:错误输出
3:运行时的jar包库
4,5是两个socket(ip4和ip6)


image.png
查看网络状态 看到了 进程id6545的java程序 监听者8090端口
image.png

阻塞IO

使用nc作为客户端建立连接之后查看状态


image.png
image.png

这个时候fd多了一个sockte连接


image.png
程序打印
image.png
查看内核状态,追踪系统调用

xxoo.6546


image.png

这段等于

  ServerSocket server = new ServerSocket(8090);
image.png

接下来分别是 监听fd5,通过poll阻塞,等到有连接了之后就接收39884端口nc的连接


image.png

是这样的,阻塞在这里(5代表socket状态处于监听)


image.png
image.png

在主线程里面,当新的客户端连接进来,使用clone来创建新的线程出去这个连接(客户端描述符为7 accept返回的结果,clone的返回结果7961,为新的线程的跟踪号)我们来查看一下


image.png image.png
image.png
image.png

客户端向服务端发送消息
服务端接收(write(1)表示打印


image.png

等到有客户端了得到fd6的socket,然后read这个流


image.png

之后再来客户端 ,主线程只负责accept得到文件描述符,之后抛出线程通过子线程去操作 recvfrom的内容,就是如上图所示


image.png

非阻塞IO

select

这是select()多路复用,把所有的文件描述符传入,内核会自动返回可读可写的状态,但是在内核里面会遍历N次文件描述符去检查状态。


image.png

Epoll

内核里面基于事件驱动的被动去自动接收有状态的文件描述符
在内核里面创建一个空间有了新的客户端文件描述符就传进来,比如socket为fd5,

首先创建一个fd8的空间epoll_create fd8
epoll_ctl可以add mod delete,操作指定的文件描述符,所以epoll_ctl(fd8,add,fd5,accept)等待接收
新的客户端
然后等到有事件发生即新的客户端连进来,通过epoll_waite内核就会知道哪个客户端,即监听这个端口,这个方法是一直在轮询执行
然后accept fd5去返回这个客户端,添加到内核里面的fd8空间里,epoll_ctl(fd8,fd6)


image.png

那么是怎么把这些知道客户端的事件呢,把绿色的放到蓝色里面去,这就是靠事件驱动来完成,就是操作系统的中断产生的数据到达,把这些有事件的文件描述符移过去。


image.png

相关文章

网友评论

      本文标题:什么是epoll

      本文链接:https://www.haomeiwen.com/subject/lqkcxktx.html