What's the difference between event-driven and asynchronous? Between epoll and AIO?
Events is one of the paradigms to achieve asynchronous execution.
But not all asynchronous systems use events. That is about semantic meaning of these two - one is super-entity of another.
epoll and aio use different metaphors:
epoll is a blocking operation (epoll_wait()
) - you block the thread until some event happens and then you dispatch the event to different procedures/functions/branches in your code.
In AIO, you pass the address of your callback function (completion routine) to the system and the system calls your function when something happens.
Problem with AIO is that your callback function code runs on the system thread and so on top of the system stack. A few problems with that as you can imagine.
Why boost::aio is asynchronous when its implementation is based on epoll(synchronous)
"synchronous" normally refers to an operation that does not return control back to the caller until it has completed.
epoll
is synchronous in the sense that its operation (returning fds with pending completions/actions) is complete by the time it returns.
Reading from or writing to a socket however is still asynchronous in the sense that the operation to read or write is still not complete when the function call returns. The actual I/O work may be done asynchronously, and epoll
will tell you when it's done. The work will be performed regardless of if and when you call epoll
, epoll
is just the mechanism to signal completions back to you, not the function that performs the work.
revisiting how do you use aio and epoll together
note you CAN use POSIX aio with epoll, there's signalfd(2)
it creates a file descriptor that you can then use to be notified of signals in an epoll based loop.
Also the second aio API is supposed to eventually be what glibc bases it's implementation of POSIX aio on, it's just not quite there yet... (I don't know if anyone is working on it either)
How do you use AIO and epoll together in a single event loop?
try libevent:
http://www.monkey.org/~provos/libevent/
there are patches to support both.
Event-driven Model in C with Sockets
You definitely must read the following: http://www.kegel.com/c10k.html. That page is the perfect overview of event-driven and asynchronous techniques.
However, a quick & dirty answer: event-driven is neither non-blocking, nor asynchronous.
Event-driven means, that the process will monitor its file descriptors (and sockets), and act only when some event occurs on some descriptor (events are: data received, error, became writeable, ...).
BSD sockets have the "select()" function. When called, the OS will monitor the descriptors, and return to the process as soon as some event on one of the descriptors occurs.
However, the website above has much better descriptions (and details about the different APIs).
Is there really no asynchronous block I/O on Linux?
The real answer, which was indirectly pointed to by Peter Teoh, is based on io_setup() and io_submit().
Specifically, the "aio_" functions indicated by Peter are part of the glibc user-level emulation based on threads, which is not an efficient implementation.
The real answer is in:
io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)
Note that the man page, dated 2012-08, says that this implementation has not yet matured to the point where it can replace the glibc user-space emulation:
http://man7.org/linux/man-pages/man7/aio.7.html
this implementation hasn't yet matured to the point where the POSIX
AIO implementation can be completely reimplemented using the kernel
system calls.
So, according to the latest kernel documentation I can find, Linux does not yet have a mature, kernel-based asynchronous I/O model. And, if I assume that the documented model is actually mature, it still doesn't support partial I/O in the sense of recv() vs read().
Getting to know the basics of Asynchronous programming on *nix
Boost ASIO :: It uses epoll under linux and thus not a true async
pattern as it spawns thread which are completely abstracted from user
code to acheive the proactor design pattern
This is not correct. The Asio library uses epoll()
by default on most recent Linux kernel versions. however, threads invoking io_service::run()
will invoke callback handlers as needed. There is only one place in the Asio library that a thread is used to emulate an asynchronous interface, it is well described in the documentation:
An additional thread per io_service is used to emulate asynchronous
host resolution. This thread is created on the first call to either
ip::tcp::resolver::async_resolve()
or
ip::udp::resolver::async_resolve()
.
This does not make the library "not a true async pattern" as you claim, in fact its name would disagree with you by definition.
1) What would be the best design pattern for writing fast scalable network server using epoll (of course, will have to use threads here :(
)
I suggest using Boost Asio, it uses the proactor design pattern.
3) Boost ASIO uses one big lock around epoll call. I didnt actually
understand what can be its implications and how to overcome it using
asio itself
The epoll reactor uses a mutex to dispatch handlers, though in practice this is not a big concern for most applications. There are application specific ways to mitigate this behavior, such as an io_service
per CPU to exploit data locality. See my answer to a similar question on this topic. It is also discussed on the Asio mailing list frequently.
4) How can I modify ASIO pattern to work with disk files? Is there any
recommended design pattern?
The Asio library does not natively support file I/O as you noted. There have been several attempts to add it to the library, I'd suggest discussing on the mailing list.
Can signals be pushed from and to self process and then handled as event on EPOLL?
Yes, you can do this. An easy way would be to create a pipe (https://linux.die.net/man/2/pipe). You can read from it in your main loop and write to it from elsewhere.
Related Topics
-Bash: /Usr/Bin/Yum: /Usr/Bin/Python: Bad Interpreter: No Such File or Directory
Writing a Program for Hiding Processes from Ps Command Result
How to Copy Folder with Files to Another Folder in Unix/Linux
How to Remove Specific Rules from Iptables
How to Get Out of 'Screen' Without Typing 'Exit'
Find the Files Existing in One Directory But Not in the Other
Rename Files and Directories (Add Prefix)
Unzip All Files in a Directory
Connect to Host Localhost Port 22: Connection Refused
Copy Files from Windows to Windows Subsystem for Linux (Wsl)
Docker Networking Namespace Not Visible in Ip Netns List
How to Force 'Cp' to Overwrite Directory Instead of Creating Another One Inside
Error: Can't Open Display: (Null) When Using Xclip to Copy Ssh Public Key
Installed Go Binary Not Found in Path on Alpine Linux Docker
Turning Multiple Lines into One Comma Separated Line
Best Way Elevate the Privileges Programmatically Under Different Versions of Linux