In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
How to carry on the wakeup analysis of Java NIO, in view of this problem, this article introduces the corresponding analysis and answer in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.
In the implementation of java NIO, there are many details that are of great learning significance, such as the following:
What is the wakeup principle of Selector? How is it realized?
Wakeup ()
To be exact, it should be the wakeup () of Selector, that is, the wake-up of Selector. Why should there be such a wake-up operation? That has to be explained from the way Selector is selected. It has been summarized earlier that there are three ways to choose Selector: select (), select (timeout), and selectNow ().
The selection process of selectNow is non-blocking and has little to do with wakeup.
The selection process of select (timeout) and select () is blocked, and other threads can call wakeup to wake up if they want to terminate the process.
The principle of wakeup
Since the Selector blocking option returns because the ready finds the event of interest (excluding timeouts, interrupts), you can construct a scenario of the event of interest ready for it. The following figure can vividly describe the principle of wakeup:
FD under the jurisdiction of Selector (file descriptor, linux is fd, which corresponds to a file and a handle under windows For each optional Channel created, the corresponding FD,Channel and FD are generated. See another article) contains a FD A, An is interested in data readable events. When the data is put (written) into the funnel end of the graph, the data flows into A, so A has an interesting event ready. Finally, select gets the result and returns it.
Wakeup is defined in Selector as follows:
Public abstract Selector wakeup ()
The following is combined with the above figure to track down the implementation of wakeup:
The default implementation of Selector under linux is PollSelectorImpl, and when the kernel version is greater than 2.6, the implementation is EPollSelectorImpl. Just looking at the wakeup methods of the two, the code seems to be exactly the same:
Public Selector wakeup () {synchronized (interruptLock) {if (! interruptTriggered) {pollWrapper.interrupt (); interruptTriggered = true;}} return this;}
The implementation of Selector under window is WindowsSelectorImpl, and its wakeup implementation is as follows:
Public Selector wakeup () {synchronized (interruptLock) {if (! interruptTriggered) {setWakeupSocket (); interruptTriggered = true;}} return this;}
Where interruptTriggered is the interrupt triggered flag, and when pollWrapper.interrupt (), the flag is true; thanks to this flag, wakeup twice in a row will have only one effect.
Comparing the above figure and the above code, in fact, pollWrapper.interrupt () and setWakeupSocket () are the process of pouring water into the funnel in the picture. regardless of windows or linux, their ideas of wakeup are exactly the same, but the difference lies in the details of the implementation. For example, the link between the funnel and the channel in the above figure is realized by pipeline pipe in linux, while the communication between two socket is used in windows. They all have the following characteristics:
1) there are two ends, one is read side and the other is write side. Two socket in windows also play the role of read and the other plays the role of write.
2) when the data is written to the write side, the read side can receive the data; from their characteristics, we can see that they are competent for the job.
If you only want to understand the principle of wakeup, it should be almost enough to see here, but below, I would like to go further to satisfy more people's curiosity.
First, take a look at the specific wakeup implementation of PollSelector under linux, and introduce it in stages:
1) preparation phase
PollSelector prepares the pipeline pipe and wakeup-specific FD when it is constructed. You can take a look at its implementation:
PollSelectorImpl (SelectorProvider sp) {super (sp, 1,1); int [] fdes = new int [2]; IOUtil.initPipe (fdes, false); fd0 = fdes [0]; fd1 = fdes [1]; pollWrapper = new PollArrayWrapper (INIT_CAP); pollWrapper.initInterrupt (fd0, fd1); channelArray = new SelectionKeyImpll [INIT _ CAP];}
IOUtil.initPipe, using the system call pipe (int fd [2]) to create the pipe, fd [0] is the read side, and fd [1] is the write side.
Another concern is pollWrapper.initInterrupt (fd0, fd1). Let's take a look at its implementation:
Void initInterrupt (int fd0, int fd1) {interruptFD = fd1; putDescriptor (0, fd0); putEventOps (0, POLLIN); putReventOps (0,0);}
To see that initInterrupt is preparing a wakeup-specific FD, because fd0 is read-side fd,fd1 is write-side fd:
InterruptFD is initialized to write-side fd
PutDescriptor (0, fd0) initializes the * pollfd in the pollfd array, that is, the * fd that PollSelector follows, that is, fd0.
PutEventOps (0, POLLIN) initializes the fd0 corresponding to the events in pollfd is POLLIN, which means that fd0 is interested in readable events
PutReventOps (0,0) is just initializing the revents in the pollfd corresponding to fd0.
2) execution phase
With the previous preparations, take a look at the interrupt () implementation in PollArrayWrapper:
Public void interrupt () {interrupt (interruptFD);}
Interrupt is the native method, and its input parameter interruptFD is the write end fd of the pipeline in the preparation phase. Corresponding to the figure above, it is actually the funnel end. Therefore, even without looking at its implementation, we also know that it must play the action of pouring water and see its implementation:
JNIEXPORT void JNICALL Java_sun_nio_ch_PollArrayWrapper_interrupt (JNIEnv * env, jobject this, jint fd) {int fakebuf [1]; fakebuf [0] = 1; if (write (fd, fakebuf, 1) < 0) {JNU_ThrowIOExceptionWithLastError (env, "Write to interrupt fd failed");}}
As you can see, interrupt (interruptFD) writes a byte (write (fd, fakebuf, 1)) to the write side of the pipe fd1.
Yes, only one byte needs to be written to fd1, and the fd0 satisfies the readable event ready, and the Selector will naturally stop blocking the return because of the event ready.
Compared with PollSelector, EPollSelector's wakeup implementation is only different from initInterrupt. Its implementation is as follows:
Void initInterrupt (int fd0, int fd1) {outgoingInterruptFD = fd1; incomingInterruptFD = fd0; epollCtl (epfd, EPOLL_CTL_ADD, fd0, EPOLLIN);}
As mentioned in the previous chapter of epfd, it is through the epoll file created by epoll_create that fd,epollCtl calls the kernel epoll_ctl to add fd0 to epfd, and the event of interest is EPOLLIN.
Therefore, it can be concluded that the wakeup implementation of EPollSelector and PollSelector is consistent.
Because we have been focusing on and analyzing the implementation of Java NIO under linux and ignoring the selection process under windows, it seems very sudden to explain its implementation of wakeup here, so we intend to set up a special article to introduce the implementation of NIO under windows. Here we only need to understand the principle of wakeup, or even to take a look at its wakeup implementation.
This is the answer to the question on how to analyze the wakeup of Java NIO. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel to learn more about it.
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.