Boost.asio Foundation (v) on asynchronous programming

Source: Internet
Author: User

Asynchronous Programming

This section discusses several issues that asynchronous programming will encounter. It is recommended to read many times in order to thoroughly understand this section, which is very important for the whole boost.asio.

Why Async is required

As mentioned earlier, synchronous programming is usually simpler than asynchronous programming. Under synchronous programming, it is easy to consider the problem linearly, the function A calls, the continuation of the execution of b,b execution, continue to execute C, and so on, relatively intuitive. And for asynchronous programming, assuming there are 5 events, it's hard to know the exact order of execution, and you don't even know if it will ever be executed.
Although it is difficult to write asynchronous programs, it is still necessary to use this method. Because the server program needs to handle a large number of clients concurrently. The more parallel clients, the more obvious are the advantages of asynchronous programming.
Suppose you have a server program that requires simultaneous processing of 1000 concurrent clients, a communication message between the client and the server, ending with ' \ n '.
This is the code in synchronous mode, using 1 threads:

using namespaceBoost::asio;structclient{Ip::tcp::socket sock;Charbuff[1024x768];//Message maximum 1024 bytes    intAlready_read;//How many bytes have been read};STD:: vector<client>clients;voidHandle_clients () { while(true) { for(intI=0; I<clients.size (); ++i) {if(Clients[i].sock.available ()) On_read (Clients[i]); }    }}voidOn_read (client& c) {intTo_read =STD:: Min (1024x768-C.already_read, C.sock.available ());    C.sock.read_some (Buffer (C.buff + c.already_read, to_read); C.already_read + = To_read;if(STD:: Find (C.buff, C.buff + C.already_read,' \ n ') < C.buff + C.already_read) {intpos =STD:: Find (C.buff, C.buff + C.alread_read,' \ n ')-C.buff;STD::stringMSG (C.buff, C.buff + pos);STD:: Copy (C.buff + pos, C.buff +1024x768, C.buff);        C.already_read-= pos;    On_read_msg (c, msg); }}voidOn_read_msg (client & C,Const STD::string& msg) {if(msg = ="Request_login") C.sock.write ("request_ok\n");Else if...}

In the task server program, you need to avoid blocking your code. Looking at the code above, we want the handle_clients () function to be as non-blocking as possible. Any time a function is blocked, messages sent from the client will wait until the function is not blocked to handle them. In order to prevent the program from being blocked, we only read it when there is data in the socket, and the implementation code is:

if(clients[i].sock.available() )on_read(clients[i]));

In the On_read function, we only read the data that the socket is really valid for, call Read_util (c.sock, buffer (...), ' \ n '), and it is a very bad choice, it will block the program until the full data is read and returned. We never know when it's going to be finished.
The bottleneck of the program is the on_read_msg () function; All input data is stuck here. On_read_msg () should try to avoid this situation, but sometimes this is completely unavoidable. (for example, when the buffer of the socket is full, the operation is bound to be blocked).
Here is the code in synchronous mode, using 10 Threads:

using namespaceBoost::asio;//... The definition here is the same as before.    BOOLSet_reading () {Boost::mutex::scope_lock lk (Cs_);if(Is_reading_)return false;Else{If_reading_ =true;return true; }    }voidUnset_reading () {Boost::mutex::scoped_lock lk (Cs_); Is_reading_ =false; }Private: Boost::mutex Cs_;BOOLIs_reading_;};STD:: vector<client>clients;voidHandle_clients () { for(intI=0; i<Ten;    ++i) {boost::thread (handle_clients_thread); }}voidHandle_clients_thread () { while(true) { for(intI=0; I<clients.size (); ++i) {if(Clients[i].sock.available ()) {if(Clients[i].set_reading ())                    {On_read (clients[i]);                Clients[i].unset_reading (); }            }        }    }}voidOn_read (client & c) {...}voidOn_read_msg (client & C,Const STD::string& msg) {...}

In order to use multi-threading, we need a synchronization mechanism, set_reading () and unset_reading () are doing this. Set_reading (), very important, it tests whether a thread is currently doing a read operation.
It can be seen that the code is more complex.
There is also a way of synchronizing programming, that is, each client allocates a thread. But as the number of concurrent clients grows, this is obviously not feasible.
Now let's look at async methods. When the client requests the data, On_read is called, sends the return data, and then waits for the next request (another asynchronous read operation is performed).
Async code, 10 Threads:

using namespaceBoost::asio;io_service Service;structClient {Ip::tcp::socket sock; Streambuf Buff;};STD:: vector<client>clients;voidHandle_clients () { for(intI=0; I<clients.size (); ++i) {async_read_util (Clients[i].sock, Clients[i].buff,' \ n ', Boost::bind (On_read, Clients[i], _1, _2)); } for(intI=0; i<Ten; ++i) Boost::thread (handle_clients_thread);}voidHandle_clients_thread () {Service_run ();}voidOn_read (client& C,Consterror_code& err, size_t read_bytes) {STD:: IStream in (&c.buff);STD::stringMsgSTD:: Getline (in, msg);if(msg = ="Request_login") C.sock.async_write ("request_ok\n", On_write);Else if...    ...//Now waits for the next read request on the same socketAsync_read_util (C.sock, C.buff,' \ n ', Boost::bind (On_read, C, _1, _2));}

Boost.asio Foundation (v) on asynchronous programming

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.