Home PC Games Linux Windows Database Network Programming Server Mobile  
  Home \ Server \ Use Epoll develop high-performance application server on Linux     - PHP generates a random password several ways (Programming)

- Examples 14 grep command (Linux)

- Android imitation UC browser scroll up and down functions (Programming)

- Linux hybrid character device (Linux)

- Packages with Snort intrusion monitoring light (Linux)

- VMware virtual machine operating system log Error in the RPC receive loop resolve (Linux)

- Linux Getting Started tutorial: Ubuntu 14.04 in the installation Sogou Pinyin (Linux)

- Changes in C # asynchronous programming model (Programming)

- Autojump: an advanced cd command in the Linux file system fast navigation (Linux)

- Linux based exercises, interview questions (Linux)

- What is Unikernel? (Linux)

- ASM required disk format process in Solaris platforms (Linux)

- Python image processing library (PIL) to install and simple to use (Linux)

- Linux Crontab Timing task command Detailed (Linux)

- Linux, security encryption to transfer files between machines (Linux)

- Hibernate Search and Lucene quick introduction (Linux)

- The Concept and Semantics of Java Memory Model (Programming)

- Ubuntu how to install and use Objective-C (Linux)

- How to use Android Studio to play more package names APK (Programming)

- Linux ban single-user mode to enhance system security (Linux)

  Use Epoll develop high-performance application server on Linux
  Add Date : 2018-11-21      

Linux epoll is to provide a multiplexing technique, similar to each platform supported by select, just epoll kernel implementations done more optimized to support more than select a file descriptor, of course, support this socket file descriptors such networks. Large concurrent access server on Linux, the current implementations are definitely through epoll.

and thread epoll

There are many developers use epoll time, will open multiple threads to perform data communication, such as a thread dedicated to accept (the early years when I personally use kqueue FreeBSD, since a basic understanding of the internal mechanisms do not have to engage in this), a thread messaging, or are used to transmit and receive separate thread.

Under normal circumstances, accept a separate thread is not necessary, accept for the kernel is concerned, the application reads data from the kernel of a little unfinished SYN queue only. For details, see Part accept:

TCP three-way handshake with the corresponding Berkeley Socket APIs introduced

Receive a separate two threads is not necessary because most of the application server, under normal circumstances, start a thread to send and receive data, send and receive the maximum amount of data bottleneck that card instead of CPU; online access server configured as a network card KM few games will apply for 1G bandwidth, which machine was how much data input and output. So we communicate thread epoll server is enough.


The basic principle of epoll

In order to allow certain friends can read more coherent, I still talk about the basic principles of epoll.

epoll external manifestations and select are the same. He provided READ, WRITE, and events such as ERROR.

Process roughly like this:

1. Application event registered interest to the kernel;

2. kernel under certain conditions, the event notification application;

3. After the application receives the event, according to event type to do the corresponding logic.


Principle Part I tell you, the place is not easy to understand, including the level trigger and edge trigger event use (this can be combined with kqueue References 1. WRITE event, consistent with the principles of) modify the details of the event and WRITE events.

Trigger level

READ event, socket recv buff data, will have to notify the application until the buff is empty.

WRITE event, socket send buff from the full data can be sent to the state, it will always notify the application until full buff.



READ event, socket recv buff data, and notifies the application only once, regardless of the application has not called read api, the next is not notified.

WRITE event, socket send buff from a full state to be able to send data only once notification.

The above explanation does not know if you can understand, we can only say so. Have questions, do some tests. In addition, the details of these things fixed after a few years ago, a few years to do this project is the direct use, it rarely involved in the details, is based on written text to understand and remember, if there is wrong, please correct me ^ - ^.


Use WRITE event

This description also look good. Probably describe, in detail see Reference 1. Roughly like this:

1. The logical layer write data to the application layer sends buff, to register click WRITE epoll event;

2. In this case the application will notify epoll a WRITE event;

3. WRITE event response function, the buff from the sending application layer read data, and then transmitting socket send api.

Because I am in a lot of the actual project, I do not see the use of epoll WRITE event to send data, specifically to talk about. Most of the items are sent directly to the queue polling application, my early projects is so dry.


epoll modification event

For this image I more deeply. Modify event epoll comparison pit father, you can not modify an event alone! How do you say? For example epoll already registered READ & WRITE event, if you want to just re-register at WRITE events and READ events unchanged, epoll_ctl API epoll is impossible, you must register READ & WRITE, this can be seen in the following code. FreeBSD's kqueue at this point to fully meet the requirements of our programmers.


Abstract epoll API

I herm socket epoll package stickers section, so that friends refer to epoll usage. Most of the errors I throw exception code is removed.

class Multiplexor
 Multiplexor (int size, int timeout = -1, bool lt = true);
 ~ Multiplexor ();

 void Run ();
 void Register (ISockHandler * eh, MultiplexorMask mask);
 void Remove (ISockHandler * eh);
 void EnableMask (ISockHandler * eh, MultiplexorMask mask);
 void DisableMask (ISockHandler * eh, MultiplexorMask mask);
 inline bool OperateHandler (int op, ISockHandler * eh, MultiplexorMask mask)
  struct epoll_event evt;
  evt.data.ptr = eh;
  evt.events = mask;
  return epoll_ctl (m_epfd, op, eh-> GetHandle (), & evt) = -1!;
 int m_epfd;
 struct epoll_event * m_evts;
 int m_size;
 int m_timeout;
 __uint32_t m_otherMasks;

Multiplexor :: Multiplexor (int size, int timeout, bool lt)
 m_epfd = epoll_create (size);
 if (m_epfd == -1)
 m_size = size;
 m_evts = new struct epoll_event [size];

 m_timeout = timeout;

 // Sys / epoll.h is no EPOLLRDHUP (0X2000), do not add EPOLLRDHUP
 m_otherMasks = EPOLLERR | EPOLLHUP;
 if (! lt)
  m_otherMasks | = EPOLLET;

Multiplexor :: ~ Multiplexor ()
 close (m_epfd);
 delete [] m_evts;

void Multiplexor :: Run ()
 int fds = epoll_wait (m_epfd, m_evts, m_size, m_timeout);
 if (fds == -1)
  if (errno == EINTR)
 for (int i = 0; i  {
  __uint32_t evts = m_evts [i] .events;
  ISockHandler * eh = reinterpret_cast (m_evts [i] .data.ptr);
  int stateType = ST_SUCCESS;
  if (evts & EPOLLIN)
   stateType = eh-> OnReceive ();

  if (evts & EPOLLOUT)
   stateType = eh-> OnSend ();

  if (evts & EPOLLERR || evts & EPOLLHUP)
   stateType = ST_EXCEPT_FAILED;

  if (stateType! = ST_SUCCESS)
   eh-> OnError (stateType, errno);

void Multiplexor :: Register (ISockHandler * eh, MultiplexorMask mask)
 MultiplexorMask masks = mask | m_otherMasks;
 OperateHandler (EPOLL_CTL_ADD, eh, masks);

void Multiplexor :: Remove (ISockHandler * eh)
 // Delete fd from epoll, do not need masks
 OperateHandler (EPOLL_CTL_DEL, eh, ALL_EVENTS_MASK);

void Multiplexor :: EnableMask (ISockHandler * eh, MultiplexorMask mask)
 MultiplexorMask masks = mask | Herm :: READ_MASK | Herm :: WRITE_MASK;
 OperateHandler (EPOLL_CTL_MOD, eh, masks | m_otherMasks);

void Multiplexor :: DisableMask (ISockHandler * eh, MultiplexorMask mask)
 MultiplexorMask masks = (Herm :: READ_MASK | Herm :: WRITE_MASK) & (~ mask);
 if (OperateHandler (EPOLL_CTL_MOD, eh, masks |! m_otherMasks))

The above class will use epoll_create (), epoll_ctl () and epoll_wait (), as well as several events. epoll up with refreshing than the select.

Usage substantially similar to the following:

Define a Handler

class StreamHandler: public Herm :: ISockHandler
 virtual Herm :: Handle GetHandle () const;
    virtual int OnReceive (int);
 virtual int OnSend (int);

In OnReceive () operation to process the received data, in OnSend (). . . .

In the communication thread, probably like this code, look at the actual situation.

Multiplexor multiplexor;
StreamHandler sh;
multiplexor.Register (& sh, READ_EVT);
multiplexor.Run (...);
- Build a Linux development environment under STC89C52RC (Linux)
- Python uses multi-process pool (Programming)
- DBCA Error: ORA-19809: limit exceeded for recovery files process (Database)
- Introduction to thread pooling and simple implementation (Programming)
- Towards Docker (Server)
- Use scripts easily install the latest Linux kernel in Ubuntu (Linux)
- SSH keys using login and password to log prohibited practice (Linux)
- Java List add duplicate the same object (Programming)
- Installation Strongswan: on a Linux IPsec-based VPN tool (Linux)
- Bash variable expansion modifier (Programming)
- After installation of Debian 6.0 do a few things first (Linux)
- Android float ball and boot from the start (Programming)
- Linux System Getting Started Learning: complete installation on Debian or Ubuntu kernel source (Linux)
- RedHat6.4 installation tutorial --- Minimal Edition (Linux)
- System Security: Build Linux with LIDS steel castle (Linux)
- To create a file in Linux directory by setfacl (Linux)
- WinSCP to transfer text files will automatically convert the format (Linux)
- jQuery update the content and method of use 3.0 (Programming)
- C ++ complex class of operator overloading (Programming)
- Configuration based on open source Lucene Java development environment (Server)
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.