当前位置:网站首页>NIO this.selector.select()
NIO this.selector.select()
2022-07-27 08:42:00 【Mangxiao】
NIO this.selector.select
Process carding :
1. SelectorImpl.lockAndDoSelect()
2. windowsSelectorImpl.doSelect Officially start polling events
2.1 subSelector.poll(); Start the bottom polling , Get ready file descriptor
2.2 this.updateSelectedKeys(); Will be ready key Add to selectedKeys in , Enter the method
2.2.1 this.subSelector.processSelectedKeys(this.updateCount); Call... On the main thread poll after , Will get the ready file descriptor ( Include readable 、 Can write 、 abnormal ). By calling processSelectedKeys Corresponding to the ready file descriptor SelectorKey Add to selectedKeys in . In this way, we can call all ready SelectorKey Do traversal processing .



SelectorImpl.lockAndDoSelect()

a key : Finally, execute SelectorImpl.doSelect, stay windows Platform by WindowsSelectorImpl Realization
WindowsSelectorImpl#doSelect


Analyze one by one
protected int doSelect(long var1) throws IOException {
// First of all to see Selector If there Channel, If not, throw an exception
if (this.channelArray == null) {
throw new ClosedSelectorException();
} else {
this.timeout = var1;
this.processDeregisterQueue();
Set interrupter , What's actually called is AbstractSelector.this.wakeup(); Method
// The method is called AbstractInterruptibleChannel.blockedOn(Interruptible);
if (this.interruptTriggered) {
this.resetWakeupSocket();
return 0;
} else {
// Adjust the number of worker threads
this.adjustThreadsCount();
// Adjust the running relationship between the main thread and the auxiliary thread
this.finishLock.reset();
this.startLock.startThreads();
try {
this.begin();
try {
// perform poll Method
this.subSelector.poll();
} catch (IOException var7) {
this.finishLock.setException(var7);
}
if (this.threads.size() > 0) {
this.finishLock.waitForHelperThreads();
}
} finally {
this.end();
}
this.finishLock.checkForException();
this.processDeregisterQueue();
int var3 = this.updateSelectedKeys();
this.resetWakeupSocket();
return var3;
}
}
}
adjustThreadsCount
As you can see from the notes , The method in NIO in channel After registration or logout , Adjust the number of worker threads . among threads.size() Is the current number of worker threads ,threadsCount For the number of worker threads needed . If the current quantity is less than the required quantity , Create a new worker thread , To achieve the required quantity . If the current quantity is greater than the required quantity , Then kill the redundant threads .

Auxiliary thread : A thread can only handle 1024 individual Channel, If there are too many, you need to provide auxiliary threads other than the main thread , In the Selector register Channel Auxiliary threads will be added according to conditions , To selector.select Will judge when .
processDeregisterQueue
Process logged out SelectionKey
updateSelectedKeys —— a key : Discovery of the arrival of the event

SubSelector
poll —— Interact with the kernel to find events of interest

processSelectedKeys —— Handle events of interest found from the kernel
updateSelectedKeys Be responsible for handling readiness events FD, Will these FD The corresponding selection key is added selectedKeys aggregate . The client traverses selectedKeys Collection can handle various events . Look at the source code
updateSelectedKeys The first call processSelectedKeys Handle the ready event on the main thread FD list . Then iteration threads The collection processes the ready events on each worker thread separately FD list . see processSelectedKeys Realization :
processSelectedKeys It's easy to implement , Deal with... Separately readFds,writeFds,exceptFds In three arrays FD, The core processing process is in processFDSet To realize 
processFDSet
To deal with readFds For example
Parameter interpretation :
var1: this.updateCount, Save the number of updates
var3: this.readFds, Readable file descriptor array , What is stored here is Channel File descriptor for , The first element of the file descriptor is the length of the array , Then comes the value of the file descriptor


private int processFDSet(long var1, int[] var3, int var4, boolean var5) {
// Store the number of prepared events
int var6 = 0;
//1. Take the readable file event as an example ,var3 Is an array of file descriptors var3[0] It represents the length of the file descriptor stored in the array
for(int var7 = 1; var7 <= var3[0]; ++var7) {
// Get the value of the file descriptor fdVal
int var8 = var3[var7];
//2. Determine whether the current file descriptor is a file description for wakeup
if (var8 == WindowsSelectorImpl.this.wakeupSourceFd) {
synchronized(WindowsSelectorImpl.this.interruptLock) {
WindowsSelectorImpl.this.interruptTriggered = true;
}
} else {
// according to fdval Get selector Medium FdMap Medium SelectionKeyImpl
WindowsSelectorImpl.MapEntry var9 = WindowsSelectorImpl.this.fdMap.get(var8);
if (var9 != null) {
// Get SelectionKeyImpl
SelectionKeyImpl var10 = var9.ski;
if (!var5 || !(var10.channel() instanceof SocketChannelImpl) || !WindowsSelectorImpl.this.discardUrgentData(var8)) {
if (WindowsSelectorImpl.this.selectedKeys.contains(var10)) {
if (var9.clearedCount != var1) {
if (var10.channel.translateAndSetReadyOps(var4, var10) && var9.updateCount != var1) {
var9.updateCount = var1;
++var6;
}
} else if (var10.channel.translateAndUpdateReadyOps(var4, var10) && var9.updateCount != var1) {
var9.updateCount = var1;
++var6;
}
var9.clearedCount = var1;
} else {
if (var9.clearedCount != var1) {
// updated SelectionKeyImpl Ready Events
var10.channel.translateAndSetReadyOps(var4, var10);
// In fact, it is to check whether the event you are interested in is a ready event , That is, the event you are interested in has passed the verification and can be processed later .
if ((var10.nioReadyOps() & var10.nioInterestOps()) != 0) {
// Will be selectionKeys Add to Selector Of set In the data structure
WindowsSelectorImpl.this.selectedKeys.add(var10);
//
var9.updateCount = var1;
++var6;
}
} else {
var10.channel.translateAndUpdateReadyOps(var4, var10);
if ((var10.nioReadyOps() & var10.nioInterestOps()) != 0) {
WindowsSelectorImpl.this.selectedKeys.add(var10);
var9.updateCount = var1;
++var6;
}
}
var9.clearedCount = var1;
}
}
}
}
}
// here var6>0, Express Channel The interested events can be processed after verification ,
return var6;
}
}

translateAndSetReadyOps



First, look into the reference var3, In fact, it is the first one we created Channel,ServerSocketChannel Corresponding SelectionKeyImpl, It is interested in reading events ( Because of its interestOps by 16, You can see in the following code )
Why 16, Because the event it is interested in is OP_ACCEPT
public boolean translateReadyOps(int var1, int var2, SelectionKeyImpl var3) {
// Take it SelectionKeyImpl Events of interest and prepared event types in
int var4 = var3.nioInterestOps(); #16
int var5 = var3.nioReadyOps(); #0
int var6 = var2;
//Net.POLLNVAL Indicates that the socket file is not open , As mentioned above var1 representative NET.POLLIN Indicates that there are readable events , Generally, this constant is defined as 00001,00010 Bits in this form , The operation of and is actually to compare whether the two are equal . It's obviously not equal here
if ((var1 & Net.POLLNVAL) != 0) {
return false;
// The meaning of this step is actually whether the event is Net.POLLERR、Net.POLLHUP One of them, one of them 00001, One is 00010, The two carry out or operation 00011, as long as var1 It's one of them , And operation is not 0 .NET.POLLIN 768 amount to 1100000000 That is to say 512+256
} else if ((var1 & (Net.POLLERR | Net.POLLHUP)) != 0) {
var3.nioReadyOps(var4);
return (var4 & ~var5) != 0;
} else {
// The meaning expressed here : This is a judgment of reading events and SelectionKeyImpl Is interested in the event of reading , Because we can see from above SelectionKeyImpl Of interestOps by 16, therefore var4 & 16) != 0 Is established
if ((var1 & Net.POLLIN) != 0 && (var4 & 16) != 0) {
//var6 =16
var6 = var2 | 16;
}
// Key step : Express SelectionKeyImpl The read event for is ready : To inform Channel: Here comes the reading event you are interested in !
var3.nioReadyOps(var6);
return (var6 & ~var5) != 0; // This step is worth detailing ,SelectionKeyImpl By bit InterestOps and ReadyOps The storage , A bit sequence can store multiple events of interest , It is the operation between bits that may make people confused , Can't , It's better to save money than brains . Here you only need to know the return true.
}
}
边栏推荐
- Management of product pictures
- 海关总署:这类产品暂停进口
- Functions and arrow functions
- Process control - Branch
- regular expression
- Solution of database migration error
- MCDF顶层验证方案
- General Administration of Customs: the import of such products is suspended
- The following license SolidWorks Standard cannot be obtained, and the use license file cannot be found. (-1,359,2)。
- Installation and use of Supervisor
猜你喜欢

4274. Suffix expression

Minio 安装与使用

First experience of tryme in opengauss

如何在qsim查看软件对象的实例?

Oppo self-developed large-scale knowledge map and its application in digital intelligence engineering

Unity3D 2021软件安装包下载及安装教程

Create a project to realize login and registration, generate JWT, and send verification code

Flask request data acquisition and response

How to upload qiniu cloud

Zhongang Mining: the new energy industry is developing rapidly, and fluorine chemical products have a strong momentum
随机推荐
第2章 前台数据展现
Vertical align cannot align the picture and text vertically
Function realization of order system
Installation and use of Supervisor
Implementation of queue (sequential storage, chain storage)
Full Permutation (depth first, permutation tree)
Map structure
General Administration of Customs: the import of such products is suspended
说透缓存一致性与内存屏障
众昂矿业:新能源行业快速发展,氟化工产品势头强劲
MySQL Express
Forced login, seven cattle cloud upload pictures
Zhongang Mining: the new energy industry is developing rapidly, and fluorine chemical products have a strong momentum
网络IO总结文
Realization of backstage brand management function
Cache consistency and memory barrier
Installation and use of beef XSS
Element display mode: block level, inline, inline block, nesting specification, display mode conversion
STM32 small bug summary
Implementation of adding function of background user management display




