In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article focuses on "Netty source code analysis NioEventLoop how to implement select", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Next let the editor to take you to learn "Netty source code analysis NioEventLoop how to implement select" bar!
The entry of select operation. The run method of NioEventLoop: protected void run () {for (;;) {try {switch (selectStrategy.calculateStrategy (selectNowSupplier, hasTasks () {case SelectStrategy.CONTINUE: continue Case SelectStrategy.SELECT: / / polling io event (1) select (wakenUp.getAndSet (false)); if (wakenUp.get ()) {selector.wakeup ();} default:} cancelledKeys = 0 NeedsToSelectAgain = false; / / defaults to 50 final int ioRatio = this.ioRatio; if (ioRatio = = 100) {try {processSelectedKeys ();} finally {runAllTasks () }} else {/ / record the start time final long ioStartTime = System.nanoTime (); try {/ / process the polled key (2) processSelectedKeys () } finally {/ / calculation time final long ioTime = System.nanoTime ()-ioStartTime; / / execute task (3) runAllTasks (ioTime * (100-ioRatio) / ioRatio);} catch (Throwable t) {handleLoopException (t) } / / Code omission}}
The code is relatively long, but it is mainly divided into three parts:
1. Polling for io events
two。 Process polled key
3. Execute task
This section mainly analyzes the first part.
Polling for io events
First of all, by default, the switch block goes to SelectStrategy.SELECT and executes the select (wakenUp.getAndSet (false)) method
The parameter wakenUp.getAndSet (false) indicates that the current select operation is unawakened.
Enter private void select (boolean oldWakenUp) throws IOException {Selector selector = this.selector; try {int selectCnt = 0; / / the number of nanoseconds of the current system long currentTimeNanos = System.nanoTime () in the select (wakenUp.getAndSet (false)) method; / / deadline = current time + remaining execution time of the first task in the queue long selectDeadLineNanos = currentTimeNanos + delayNanos (currentTimeNanos); for ( ) {/ / blocking time (Ms) = (cutoff time-current time + 0.5ms) long timeoutMillis = (selectDeadLineNanos-currentTimeNanos + 500000L) / 1000000L If (timeoutMillis = timeout (condition is established, one select operation has been performed, and empty polling may occur if the condition is not valid) if (time-TimeUnit.MILLISECONDS.toNanos (timeoutMillis) > = currentTimeNanos) {/ / indicates that a blocking select operation has been performed and the number of operations has been reset to 1 selectCnt = 1 } else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 & & selectCnt > = SELECTOR_AUTO_REBUILD_THRESHOLD) {/ / omit the log code / / if the number of empty polls is greater than a threshold, bug rebuildSelector () solves empty polling; selector = this.selector; selector.selectNow () SelectCnt = 1; break;} currentTimeNanos = time;} / / Code omission} catch (CancelledKeyException e) {/ / omit}}
First, get the number of nanoseconds of the system by long currentTimeNanos = System.nanoTime ()
Continue to look down:
Long selectDeadLineNanos = currentTimeNanos + delayNanos (currentTimeNanos)
DelayNanos (currentTimeNanos) represents the time remaining from the first task in the scheduled task. This time + current time represents the time that cannot be exceeded in this operation, because the scheduled task cannot be executed strictly according to the scheduled time. The scheduled task queue is a queue that has been arranged from small to large according to the execution time, so the first task is the most recent task that needs to be executed. SelectDeadLineNanos represents the time that the current operation cannot exceed.
And then into the infinite for loop.
In the for loop, we focus on:
Long timeoutMillis = (selectDeadLineNanos-currentTimeNanos + 500000L) / 1000000L
SelectDeadLineNanos-currentTimeNanos+500000L represents the cutoff time-current time + 0.5ms adjustment time, divided by 1000000 to convert the calculated time into milliseconds
The final calculated time is the blocking time of the selector operation and is assigned to the timeoutMillis of the local variable
After that, there is a judgment if (imeoutMillis= currentTimeNanos), which means the current time-blocking time > the time when the method starts to execute. This indicates that a blocking select () operation has been completed and selectCnt is set to 1.
If this condition is not true, it means that the select () operation has not been fully executed, and an empty polling may have been triggered. According to the previous selectCnt++ step, we know that each empty polling selectCnt will increase itself.
After that, we will enter the second judgment SELECTOR_AUTO_REBUILD_THRESHOLD > 0 & & selectCnt > = SELECTOR_AUTO_REBUILD_THRESHOLD.
SELECTOR_AUTO_REBUILD_THRESHOLD defaults to 512.If the number of empty polls exceeds 512, it will be thought that epoll bug has occurred, so the selector will be rebuilt through the rebuildSelector () method, and then the reconstructed selector will be assigned to the local variable selector, and selectNow () will be executed once, initializing selectCnt 1, and jumping out of the loop.
In the rebuildSelector () method, see how netty solves whether epoll bug's public void rebuildSelector () {/ / whether if (! inEventLoop ()) is initiated by another thread, encapsulates rebuildSelector () into a task queue, and NioEventLoop calls execute (new Runnable () {@ Override public void run () {rebuildSelector ()). }}); return;} final Selector oldSelector = selector; final Selector newSelector; if (oldSelector = = null) {return;} try {/ / re-create a select newSelector = openSelector ();} catch (Exception e) {logger.warn ("Failed to create a new Selector.", e); return;} int nChannels = 0 For (;) {try {/ / get all the key for (SelectionKey key: oldSelector.keys ()) {Object a = key.attachment (); try {Object a = key.attachment () in the old select / / Code omission / / get the event registered by key int interestOps = key.interestOps (); / / cancel the event registered by key key.cancel () / / register with the recreated new selector SelectionKey newKey = key.channel () .register (newSelector, interestOps, a); / / if channel is NioChannel if (an instanceof AbstractNioChannel) {/ / reassign ((AbstractNioChannel) a) .selectionKey = newKey } nChannels + +;} catch (Exception e) {/ / Code ellipsis} catch (ConcurrentModificationException e) {continue;} break;} selector = newSelector; / / Code ellipsis}
It will first determine whether it is executed by the current NioEventLoop thread, and if not, encapsulate the build method into task to be executed by the current NioEventLoop
Final Selector oldSelector = selector means to get the old selector
Then create a new selector with newSelector = openSelector ()
Traverses all key registered in selector through a for loop
Object a = key.attachment () is to get the channel. As mentioned in the first chapter, when registering, bind yourself to the key as an attribute.
In the body of the for loop, get the registered events through int interestOps = key.interestOps ()
Key.cancel () cancels the registered event
SelectionKey newKey = key.channel () .register (newSelector, interestOps, a) registers channel and registered events in the new selector
If (an instanceof AbstractNioChannel) determines whether it is NioChannel or not.
If it is NioChannel, assign its own property selectionKey to the newly returned key through ((AbstractNioChannel) a) .selectionKey = newKey
Selector = newSelector assigns its own NioEventLoop attribute selector to the newly created newSelector
At this point, the step for netty to solve the epoll bug is to create a new selector, re-register the channel and events registered in the old selector into the new selector, and then replace its selector attribute with the newly created selector.
At this point, I believe that everyone on the "Netty source code analysis NioEventLoop how to implement select" have a deeper understanding, might as well to the actual operation of it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.