[英]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.