当前位置:网站首页>Block, non block, multiplexing, synchronous, asynchronous, bio, NiO, AIO

Block, non block, multiplexing, synchronous, asynchronous, bio, NiO, AIO

2022-06-23 16:13:00 InfoQ

About IO It's going to involve blocking 、 Non blocking 、 Multiplexing 、 Sync 、 asynchronous 、BIO、NIO、AIO Wait for a few knowledge points . Although the knowledge points are not difficult, they are often confused , We inform you Mark Next , Let me share with you .

1  Blocking and non blocking

1.1  Blocking

null
​ Blocking IO Under the circumstances , When the user calls read after , User threads are blocked , When the kernel data is ready and the data is copied from the kernel buffer to the user mode buffer read Will return . You can see two parts of the blockage .
  • CPU Read data from disk to kernel buffer .
  • CPU Copy data from the kernel buffer to the user buffer .

1.2  Non blocking

null
Non blocking IO issue read The data is not ready after the request , Will continue to carry on , At this point, the application will continuously poll polling The kernel asks if the data is ready , When the data is not ready , The kernel immediately returns EWOULDBLOCK error . Until the data is copied to the application buffer ,read Request to get results . And you have to pay attention to ! Here for the last time  read  Call the process of getting data , It's a synchronous process , It's a waiting process . Synchronization here means
The process of copying kernel state data to the user program's cache
.

1.3 IO Multiplexing

null
When no data is available in the non blocking case , Every time an application polls the kernel to see if the data is ready, it also costs CPU, Can you keep it from polling , When the kernel buffer data is ready , When the event notification mechanism tells the application process that the data is ready ? When the application process does not receive the event notification signal that the data is ready, it can be busy with other work . here
IO Multiplexing
That comes in handy .
IO Multiplexing Chinese makes people think big ,IO The original text of multiplexing is called  I/O multiplexing, there  multiplexing  It refers to tracking each and every one of them through records in a single thread Sock(I/O flow ) To manage multiple at the same time I/O flow .  The purpose of the invention is to improve the throughput of the server as much as possible . Implement a thread to monitor multiple IO request , Which one? IO Copy the data from the kernel to the process buffer on request , It's blocked during copying ! It is now possible to use mmap The method of address mapping , Achieve memory sharing effect , Avoid true replication , Increase of efficiency .
null
​ image
select、poll、epoll 
All are I/O The concrete realization of multiplexing .

1.3.1 select

select It's the first edition IO Reuse , A lot of problems have been leaked since it was put forward .
  • select  The parameter array passed in will be modified , This is for a function that needs to be called many times , It's very unfriendly .
  • select  If any one sock(I/O stream) There's data ,select  Just going back to , But I won't tell you it's that sock There's data on , I can only search by myself .
  • select  Only surveillance 1024 A link .
  • select  Not thread safe , If you put one sock Add to select,  And then suddenly another thread finds this sock no need , To withdraw , This select  Don't support .

1.3.2 poll

poll  Repair the  select  A lot of questions .
  • poll  Removed 1024 Link restrictions .
  • poll  By design, the incoming array is no longer modified .
however poll Still not thread safe ,  This means that no matter how powerful the server is , You can only deal with one group in one thread  I/O  flow . Of course, you can cooperate with many processes , But then you have all sorts of problems with multi process .

1.3.3 epoll

epoll  Can be said to be  I/O  The latest implementation of multiplexing ,epoll  Repair the poll  and select Most of the problems ,  such as :
  • epoll  Now it's thread safe .
  • epoll  Now not only tell you sock Data in the group , I will also tell you which sock There's data , You don't have to find it yourself .
  • epoll  Kernel state manages all kinds of IO File descriptor ,  Previously, user mode sent all file descriptors to kernel mode , Then kernel state is responsible for filtering and returning available arrays , Now? epoll All file descriptors exist in kernel mode , You don't need to transfer file descriptors when querying .

1.3.4  Comparison between the three

null
The horizontal axis  Dead connections  It means the number of links , The name is just the name of its testing tool deadcon. The vertical axis is the number of requests processed per second , You can see epoll The number of requests processed per second will not decrease with the number of links .poll  and /dev/poll  It's very sad . but  epoll  The fatal drawback is that only
linux
Support .
Like normal Nginx Why can we support 4W Of QPS Because it will use the most efficient... On the target platform I/O Multiplexing model .

1.4  asynchronous IO

null
​ Then you will find that none of the operations mentioned above are really asynchronous , Because the two stages have to wait for a while ! And real asynchrony  I/O  There is no need to wait for kernel data preparation and data copy from kernel state to user state .
Very fortunate ,Linux For us
aio_read
Follow
aio_write
Function to achieve real asynchronous , When the user initiates aio_read The request will automatically return . The kernel will automatically copy data from the kernel buffer to the user process space , The application process doesn't care about anything .
【 Article Welfare 】 In addition, Xiaobian also sorted out some C++ Back-end development interview questions , Teaching video , Back end learning roadmap for free , You can add what you need :
Click to join the learning exchange group ~
  Group file sharing
Xiaobian strongly recommends C++ Back end development free learning address :
C/C++Linux Server development senior architect /C++ Background development architect
null

2  Synchronous and asynchronous

2.1  Sync

The difference between synchronous and asynchronous is whether the copying of data from kernel space to user space is done by user threads , There are synchronous blocking and synchronous non blocking .
  • Synchronous blocking : At this point, a thread maintains a connection , The thread completes the whole process from data reading and writing to processing , When reading and writing data, the thread is blocked .
  • Synchronous nonblocking : Nonblocking means that after a user thread makes a read request , Read requests do not block the current user thread , However, the user thread should continue to actively judge whether the data is ready OK 了 . At this point, it will still block waiting for the kernel to copy data to the user process . He's in sync with BIO The difference is using a connection to wait all the way
Let's take synchronous nonblocking as an example , As you can see below , In the process of copying data from the kernel to user space , Is done by user thread blocking .
null

​2.2  asynchronous

For asynchrony , After the user reads or writes , Will return immediately , The kernel reads and copies the data , Inform the user when finished , And execute the callback function ( user-provided callback), At this point, the data has been copied from the kernel to user space , The user thread only needs to process the data , No need to focus on reading and writing , Users don't have to wait for the kernel to copy data , When the user is notified, the data has been copied to the user space . Let's take the following example of real asynchronous non blocking .
null
​ Can be found , The user will return immediately after the call , The kernel copies the data , And notify the user thread , Make a callback .

2.3  Synchronous versus asynchronous

Message communication mechanism of synchronous attention synchronous communication, When a call is made , Before we get results , The call does not return . But once the call returns , You get the return value . let me put it another way , It is for the caller to wait for the result of the call .
Asynchronous focus on message communication mechanism asynchronous communication, The call is made after , This call returns directly , So no results returned . let me put it another way , When an asynchronous procedure call is issued , Callers don't get immediate results . But after the call is issued , The callee passes through the State 、 Notify to notify the caller , Or handle the call through a callback function .

3 Java IO

stay Java in , We use socket Network communication ,IO There are three main modes , It mainly depends on
The kernel support
Which? .
  • BIO: Synchronous blocking IO.
  • NIO: Synchronous nonblocking IO.
  • AIO: Asynchronous non-blocking IO.

3.1 BIO

Synchronous blocking IO
, For each client Socket Connection request , The server will have a processing thread corresponding to it , Connections that are not assigned to the processing thread are blocked or rejected . It's equivalent to one connection and one thread .
null
BIO characteristic
  • Use a separate thread to maintain a socket Connect , As the number of connections increases , Put some pressure on the virtual machine .
  • Using streams to read data , The flow is blocked , When there is no readability / When data can be written , Thread waiting , It wastes resources .

3.1.1 BIO  Examples

Constant :
public class Constant {
 public static final String HOST = "127.0.0.1";
 public static final int PORT = 8080;
}
The main class :
public class ClientMain {
 public static void main(String[] args) {
 // Opening service
 System.out.println(" Opening service , Listening port :" + Constant.PORT);
 new Thread(new ServerThread()).start();
 // Build a socket client , Initiate request
 System.out.println(" client , Request connection , And send data ");
 try {
 Socket socket = new Socket(Constant.HOST,Constant.PORT);
 // Turn on new thread processing socket Connect
 new Thread(new ClientProcessThread(socket)).start();
 } catch (IOException e) {
 e.printStackTrace();
 }

 }
}
Server monitoring thread :
//  Turn on the service listener thread , When a connection request is received , Open a new thread to process
public class ServerThread implements Runnable{
 @Override
 public void run() {
 try {
 ServerSocket serverSocket = new ServerSocket(Constant.PORT);
 while (true){
 Socket socket = serverSocket.accept();
 new Thread(new ServerProcessThread(socket)).start();
 // Start a new thread to process the connection request
 }
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}
Server processing thread :
import java.io.*;
import java.net.Socket;
/**
 *  After the server receives the connection request , The thread that processes the request , Blocking type IO
 */
public class ServerProcessThread implements Runnable {
 private Socket socket;
 public ServerProcessThread(Socket socket){
 this.socket = socket;
 }
 @Override
 public void run() {
 // Get client data , And write back
 // Waiting response
 try {
 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 String line = "";
 String requestStr = "";
 System.out.println(" Data from the client :"); //  Read client data
 while((line = bufferedReader.readLine()) != null){
 requestStr += line;
 System.out.println(line);
 }
 //  Send data from the server to the client
 Writer writer = new OutputStreamWriter(socket.getOutputStream());
 writer.write("data from server " + requestStr + "\r\n");
 writer.flush();
 writer.close();
 bufferedReader.close();
 socket.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}
client :
/**
 *  Maintain the client socket Connecting threads , Blocking type IO
 */
public class ClientProcessThread implements Runnable {
 private Socket socket;
 public ClientProcessThread(Socket socket){
 this.socket = socket;
 }
 @Override
 public void run() {
 // Writing data , Waiting response , Output response
 String requestStr = "data from client \r\n";
 try {
 Writer writer = new OutputStreamWriter(socket.getOutputStream());
 writer.write(requestStr);
 writer.flush();
 socket.shutdownOutput();
 // Waiting response
 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 String line;
 System.out.println(" Response from the server :");
 while((line = bufferedReader.readLine()) != null){
 System.out.println(line);
 }
 writer.close();
 bufferedReader.close();
 socket.close();

 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}

null

3.2 NIO

Synchronous nonblocking IO And NIO
: The server side saves a Socket Connection list , Then poll the list , If you find someone Socket When there is data to read on the port, it means that it is ready to read , Call this socket The corresponding read operation of the connection . If you find someone  Socket When there is data to write on the port, it indicates that it is ready to write , Call this socket The corresponding write operation of the connection . If a port's Socket The connection has been broken , Call the corresponding destruct method to close the port . This makes full use of server resources , Efficiency has been greatly improved , It's going on IO The operation request is processed by a thread , It's a request for a thread .Java Use in Selector、Channel、Buffer To achieve the above effect .
null
Each thread contains one Selector object , It's equivalent to a channel manager , It can realize the purpose of processing multiple channels in one thread , Reduce the number of threads created . The remote connection corresponds to a channel, Data is read and written through buffer All in the same channel Finish in , And the reading and writing of data is non blocking . After the channel is created, it needs to be registered in selector in , At the same time, you need to register events of interest for this channel ( Client connection server event 、 The client connects to the server 、 Read events 、 Write events ),selector Threads need to be called in rotation selector Of select function , Until the event of interest occurs in all registered channels , Then return to , Otherwise, it will be blocked all the time . Then loop through all the ready events of interest . The above steps solve BIO The two bottlenecks of the project :
  • You don't have to create threads for each connection .
  • Data read and write non blocking .
Here is a brief introduction to the following three concepts ,Java NIO It consists of the following three core parts :
  • selector
    :Selector  Allow a single thread to handle multiple Channel. If your app has multiple connections open ( passageway ), But the traffic for each connection is very low , Use Selector It will be very convenient . To use Selector, Direction Selector register Channel, And then call him. select Method , This method will block until an event is ready on a registered channel . Once this method returns , Threads can handle these events , Examples of events come in with new connections , Data reception, etc .
  • Channel
    : Basically all IO stay NIO All from one Channel Start .Channel It's kind of like a stream , Data can be obtained from channel
    read
    To buffer, You can also get it from buffer
    Write
    To channel.
  • Buffer
    : Buffer is essentially a block of memory that can read and write data , It can be understood as a container object ( With array ), The object provides a set of methods , Can use memory block more easily , Buffer objects have built-in mechanisms , It can track and record the state transition of buffer ,Channel Provide documentation from , Network access to data , But the data read or written must pass through Buffer.
channel and buffer There are several types of . Here is Java NIO Some of the main channel The implementation of the :
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
As you can see , These channels cover UDP and TCP The Internet IO, And documents IO. Here are Java NIO The key buffer Realization :
ByteBuffer
CharBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
In the microservice phase , A request may involve multiple cross server calls between different services , If you want to achieve high performance PRC Framework for data transmission , That can be based on Java NIO Make a long connection 、 Custom protocol 、 High concurrency framework , such as Netty.Netty It is based on NIO Network framework of ,  Encapsulates the Java NIO Those complex underlying details , Provides you with easy to use abstract concepts for programming . such as
Dubbo
The bottom layer is used Netty.
null

3.3 AIO

AIO It's asynchronous non blocking IO, comparison NIO Further more , When a process reads data, it is only responsible for sending and receiving instructions , The preparation of data is completely handled by the operating system .

Reference material

null
​ Recommend a zero sound education C/C++ Free open courses developed in the background , Personally, I think the teacher spoke well , Share with you :
C/C++ Background development senior architect , The content includes Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK, Streaming media ,CDN,P2P,K8S,Docker,TCP/IP, coroutines ,DPDK Etc , Learn now

original text :
Blocking 、 Non blocking 、 Multiplexing 、 Sync 、 asynchronous 、BIO、NIO、AIO  One pot
原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206231533014007.html