Multiplexes I / O programming and asynchronous RPC frame

background

In the article "unix network programming" (12) five kinds of I / O model mentioned five I / O model, in which the first four: blocking model, non-blocking model, signal drive model, I / O multiplexing model is synchronization model; there is a asynchronous model.

For multiplexed from I / O to asynchronous programming framework and RPC, to write a series of articles describes the evolution of this process, this series might include:

  1. IO multiplexing model
  2. Introduction and use epoll
  3. Reactor model and Proactor
  4. Why asynchronous programming
  5. enable_shared_from_this usage analysis
  6. Network communication and RPC libraries

Why multiplex?

Multiplexing technology to solve is "communication" problem, solve the core is the "Synchronization event separator" (de-multiplexer), select linux system with a separator of, poll, epoll online more introduction, we can see reading this article describes the good: the best explanation I've read epoll . Want to know the other party to the communication of the state (to decide what to do), there are two ways: first, polls, and second, message notification.

polling

Polling a typical implementation might look like this: Here, of course epoll_wait () may also be used poll () or select () replacement.

whiletrue) {
    active_stream[] = epoll_wait(epollfd)
    for i in active_stream[] {
        read or write till
    }
}

Polling mainly has the following disadvantages:

  • Increase system overhead. Whether it is the task polling or polling timer corresponding need to consume system resources.
  • Not been able to perceive changes in machine condition. Device status changes during the polling interval only be found in the next poll, which will not meet the sensitive real-time applications.
  • Waste of CPU resources. Whether the device state change occurs, the total polling performed. In practice, the state of most devices do not usually change so frequently, polling will be wasted idle CPU time slice.

notification

Its implementation is usually: "blocked - notice" mechanism. Blocking results in a task (task_struct, processes or threads) can only deal with a "I / O stream" or similar operations, to handle multiple, multiple tasks necessary (requires multiple processes or threads), and therefore flexibility but not as good as polling (a task enough), very contradictory.

 

select, poll, epoll Comparative

The root causes of conflict is the "one" and "many" contradictions: I hope that a task processing multiple objects, while avoiding blocking process - the internal details of the notification mechanism. The solution is to multiplex (muliplex). There are three basic multiplexing scheme, select () / poll () / epoll (), it is to resolve this contradiction.

  • The Notification Agent: Users need to care about the subject of registration to select () / poll () / epoll () function.
  • Many: all objects are concerned, as long as there is an object with the notification event, select () / poll () / epoll () will end blocked state.
  • Convenience: the user (programmer) do not have to care about how blocked and notifications, and notification will be generated under what circumstances. This thing has been done by the number of system calls, and users only need to implement "notice to me what to do."

 

So what is the difference between the top three system calls is it?
First select (), a combination of polling and blocking two ways, there is no problem, there is a time when an object event, select () just know that an event happened, exactly which one happens, do not know, polling again required from start to finish, the complexity is O (n). poll function select function relatively little change, but the maximum number of objects to enhance the pollable. epoll function to down time complexity O (1).

 

Why select epoll slow and high efficiency?
select () the reason why slow for several reasons: Parameter select () is an array of FD, means that each select call, is a new registration - blocking - callback, each must select from an array to a user after the copy space to the kernel space, to an object detected by the kernel and writes the state change, and then copied from the kernel space back to the user space, then the array is read again SELECT, and returns. This process is very inefficient.

epoll solution is the equivalent of an algorithm to select () optimization: It select () function to do a thing broken down into three steps, first epoll_create () to create a epollfd objects (equivalent to a pond), then all listening fd by epoll_ctrl () registered to the pool, which is designated an internal callback function (such as each fd, there is no back and forth when copies of each call, an array of user space to kernel space only this one copy ). epoll_wait blocked waiting. In kernel mode and has a function call corresponding epoll_wait, the ready fd, filled into a ready list, and epoll_wait read the ready list, so that the quick return (O (1)).

Can refer to a detailed comparison between the summed difference SELECT, poll, the epoll: https://www.cnblogs.com/Anker/p/3265058.html?spm=ata.13261165.0.0.4ec468f3ruw05F

 

With the above principles introduced, for example here to illustrate the next epoll in the end is how to use, to deepen understanding. Here are two examples:

It is a relatively simple example of a parent and child communication, a single applet, not need to run multiple application instances, no user input. https://www.cnblogs.com/goya/p/11903838.html
one that is more combat socket + epoll, after all, the real case can there be between the two parent and child communication so simple scenario.

With multiplexing, is not that enough?

有了I/O复用,有了epoll已经可以使服务器并发几十万连接的同时,维持高TPS了,难道这还不够吗?答案是,技术层面足够了,但在软件工程层面却是不够的。例如,总要有个for循环去调用epoll,总来处理epoll的返回,这是每次都要重复的工作。for循环体里面写什么----通知返回之后,做事情的程序最好能以一种回调的机制,提供一个编程框架,让程序更有结构一些。另一方面,如果希望每个事件通知之后,做的事情能有机会被代理到某个线程里面去单独运行,而线程完成的状态又能通知回主任务,那么"异步"的进制就必须被引入。

所以,还有两个问题要解决,一是"编程框架",一是"异步"。我们先看几个目前流行的框架,大部分框架已经包含了某种异步的机制。我们接下来的篇章将介绍“编程框架”和“异步I/O模型”。

Guess you like

Origin www.cnblogs.com/goya/p/11905248.html