[英]Why Tomcat's Non-Blocking Connector is using a blocking socket?
我正在阅读非阻塞I / O,java NIO和tomcat连接器,查看了tomcat的NIO Connector的代码,并在NioEndpoint.bind()
找到了这个 :
serverSock.configureBlocking(true); //mimic APR behavior
我没有NIO的经验,所以有人可以解释当套接字配置为阻塞时它是如何非阻塞的吗?
看起来在此次提交中引入了以下行:https://github.com/apache/tomcat/blob/bd8122700c2e70e5adbaddcd289fb1a974f981fe/java/org/apache/tomcat/util/net/NioEndpoint.java
据我所知,NioEndpoint正在使用阻塞ServerSocketChannel来阻止和等待传入连接,并且只有在接受它之后才以非阻塞方式处理这个传入套接字通道(请参阅setSocketOptions方法)。
使得ServerSocketChannel成为非阻塞的替代方法将导致作者指出忙读 - 即线程将不断轮询传入连接,因为非阻塞模式下的accept()可能返回null。
你可以在这里找到一些有用的解释。
PS我认为神秘的APR代表Apache Portable Runtime。
看完代码后:
serverSock
对象正在侦听传入连接是否阻塞 。 与其新接受的连接关联的socket
通道对象是实现非阻塞 I / O的对象。
作为侦听传入连接的线程的Acceptor class
在其run
方法中具有以下定义:
protected class Acceptor extends AbstractEndpoint.Acceptor {
@Override
public void run() {
// Loop until we receive a shutdown command
while (running) {
// Loop if endpoint is paused
while (paused && running) {
...
try {
........
SocketChannel socket = null;
try {
// Accept the next incoming connection from the server
// socket
socket = serverSock.accept();
} catch (IOException ioe) {............}
...................
// setSocketOptions() will add channel to the poller
// if successful
if (running && !paused) {
if (!setSocketOptions(socket)) {
countDownConnection();
closeSocket(socket);
}
} ....
正如您所看到的那样,它是处理新socket
的setSocketOptions
方法,它具有以下代码:
protected boolean setSocketOptions(SocketChannel socket) {
// Process the connection
try {
//disable blocking, APR style, we are gonna be polling it
socket.configureBlocking(false);
Socket sock = socket.socket();
socketProperties.setProperties(sock);
与用于在相应连接的端点中发送/接收数据的每个连接相关联的socket
通道对象是真正实现non-blocking I/O
的socket
通道对象。
尽管可以始终将serverSock
对象accept
方法设置为非阻塞,但我认为将select
(即accept)操作设置为非阻塞是不切实际的,并且不会服务于任何实际目的,并且在任何实际上下文中都不会有用。 我想不出任何非阻塞接受操作有用的用例。 那对我来说。
从呼叫者的角度看非阻塞。 API仍然需要使用阻塞(在工作线程中)或异步I / O来实际完成操作。 否则,套接字将需要一个自旋锁,并产生CPU浸泡。
您需要查看实现的其余部分,以了解如何完成此映射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.