Netty's Thread wakeup [Continued]

Before Netty's thread wakeup This article describes how to wake up a listening thread in Netty.Next we'll look at its implementation by combining some commands and experiments with some source code.

// WakeUp.java
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.net.ServerSocket;

public class WakeUp {

    public static void main(String[] args) throws Exception {
        
        // Bottom Create Pipe and Epoll
        final Selector selector = Selector.open();
        // Create socket s for listening
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        ServerSocket socket = serverSocketChannel.socket();

        socket.bind(new InetSocketAddress("127.0.0.1", 8080), 64);
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        new Thread() {
            @Override
            public void run() {
                try {
                    System.out.print("Thread[" + Thread.currentThread().getName() + "]invoke select\r\n");
                    // Thread blocked here
                    int readyChannels = selector.select();
                } catch (Exception x) {
                    x.printStackTrace();
                }
                System.out.print("Success...\r\n");
            }
        }.start();
    }
}

Let's start with the first sentence

Selector selector = Selector.open();

This sentence is to create a Selector, on Linux, in the EpollSelectorImpl.java file.

We can understand that

Selector selector = new EPollSelectorImpl(sp);

A pipe is created using the makePipe(false) method, with one end represented by int fd0 and the other end represented by int fd1.

Pipelines write data from one end and read data from the other.Pipelines belong to half duplex communication.

The next step is to create epoll-related information.

Readers and friends learn about epoll and other related multiplexing knowledge

The next step is to add one end of the pipe to the red and black tree of epoll, which will be supervised by epoll.

Adds fd0 to the epoll management, so when we write data to fd1, epoll finds that fd0 has data to read (data flows from FD1 to fd0), and wakes up the thread corresponding to epoll (pictures follow, which can be visualized).

When we execute the Java program above, we can clearly see this pipeline by looking at the file descriptor of the process


File Descriptor 8 is used to listen for client connections.

File descriptors No. 5 and 8 are added to the epoll and left to the epoll to manage.

To summarize, create an epoll socket to manage other file descriptors.Create a pipe where one end of the pipe (socket 5) is handed over to epoll and the service end socket 8 is handed over to epoll.The effect is as follows

The 7epoll socket manages Pipeline 5 and 8. Even if the client is not connected to the 8th listening socket at this time, the IO thread is blocked. We can still write data through Pipeline 6, and then epoll listens for data coming from Pipeline 5, so it is possible to wake up the IO thread.It doesn't matter what data we write to Pipeline 6. For example, in the video below, we write a 1 to Pipeline 6, and even if we don't write anything, we can still wake up the blocked IO thread.

I made a short demo video. Video Address
In the video, the echo command writes data to one end of the pipe, so epoll'finds'data coming from the other end of the pipe and wakes up from the blocked state'.

Above, on Linux, waking the select thread is piped, whereas on Windows, it is not.

Pipelines are a way of communicating between processes

We compiled and ran the Java code above on the Windows platform


View through the TCPView tool

We found that there is a pair of TCP connections in the process, which is what the TCP connections do like the above pipelines to wake up threads blocked in the select method.We can see if threads blocked in the select method will wake up by closing a TCP connection.

I made a short demo video. Video Address
In the video, by closing a TCP connection and sending data to the TCP of the other end, epoll'discovers that the other end of TCP is closed and wakes up from the blocking state'.



This article mainly explains how IO threads blocked in the select method wake up on Linux and Windows platforms. On Linux platforms, they wake up via pipeline, while on Windows platforms, they are connected via TCP.

Personal Site
Sparrow

Public Number

Tags: Java Linux

Posted on Mon, 13 Sep 2021 12:19:07 -0400 by herod1