Chapter 4. Getting Started with Boost.Asio

We already know about the Boost C++ library in general. Now it is time to find out more about Boost.Asio, the library that we use to develop network applications. Boost.Asio is a collection of libraries that are used to process data asynchronously because Asio itself stands for Asynchronous I/O (input and output). Asynchronous means that a particular task in a program will operate without blocking other tasks and Boost.Asio will notify the program when it has finished carrying out that task. In other words, the task is executed concurrently.

In this chapter, we are going to discuss the following topics:

  • Distinguishing between concurrent and nonconcurrent programming
  • Understanding the I/O service, the brain and the heart of Boost.Asio
  • Binding a function dynamically to a function pointer
  • Synchronizing access to any global data or shared data

Getting closer to the Boost.Asio library

Imagine we are developing an audio downloader application and we want the user to be able to navigate to all the menus in the application, even when the downloading process is in progress. If we do not use asynchronous programming, the application will be blocked by the downloading process and the user will have to wait until the downloading of the file is complete. But thanks to asynchronous programming, the user does not need to wait until the download process is complete to continue using the application.

In other words, a synchronous process is like queuing in a theater ticketing line. We will be served only if we reach the ticket counter and before that, we have to wait for all the processes of the previous costumers who are in front of us in the line to be completed. In contrast, we can imagine that the asynchronous process is like dinning in a restaurant where the waiter does not have to wait for the order of a customer to be prepared by the cook. Instead of blocking the time and waiting for the cook, the waiter can go and take orders from other customers.

The Boost libraries also have the Boost.Thread library that is used to execute tasks concurrently, but the Boost.Thread library is used to access internal resources, such as the CPU core resource, while the Boost.Asio library is used to access external resources, such as network connections, because the data is sent and received by a network card.

Let's distinguish between concurrent and nonconcurrent programming. Take a look at the following code for this:

/* nonconcurrent.cpp */
#include <iostream>

void Print1(void) {
  for(int i=0; i<5; i++) {
    std::cout << "[Print1] Line: " << i << "
";
  }
}

void Print2(void) {
  for(int i=0; i<5; i++) {
    std::cout << "[Print2] Line: " << i << "
";
  }
}

int main(void) {
  Print1();
  Print2();
  return 0;
}

The preceding code is a nonconcurrent program. Save the code as nonconcurrent.cpp and then compile it using the following command:

g++ -Wall -ansi nonconcurrent.cpp -o nonconcurrent

After running nonconcurrent.cpp, an output like this will be displayed in front of you:

Getting closer to the Boost.Asio library

We want to run two functions: Print1() and Print2(). In nonconcurrent programming, the application runs the Print1() function first and afterwards, completes all the instructions in the function. The program continues to invoke the Print2() function until the instruction is run completely.

Now, let's compare nonconcurrent programming with concurrent programming. For this, take a look at the following code:

/* concurrent.cpp */
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <iostream>

void Print1() {
  for (int i=0; i<5; i++) {
    boost::this_thread::sleep_for(boost::chrono::milliseconds{500});
    std::cout << "[Print1] Line: " << i << '
';
  }
}

void Print2() {
  for (int i=0; i<5; i++) {
    boost::this_thread::sleep_for(boost::chrono::milliseconds{500});
    std::cout << "[Print2] Line: " << i << '
';
  }
}

int main(void) {
  boost::thread_group threads;
  threads.create_thread(Print1);
  threads.create_thread(Print2);
  threads.join_all();
}

Save the preceding code as concurrent.cpp and compile it using the following command:

g++ -ansi -std=c++11 -I ../boost_1_58_0 concurrent.cpp -o concurrent -L ../boost_1_58_0/stage/lib -lboost_system-mgw49-mt-1_58 -lws2_32 -l boost_thread-mgw49-mt-1_58 -l boost_chrono-mgw49-mt-1_58

Run the program to get the following output:

Getting closer to the Boost.Asio library

We can see from the preceding output that the Print1() and Print2() functions are run concurrently. The Print2() function does not need to wait for the Print1() function to finish executing all the instructions that are to be invoked. This is why we call this concurrent programming.

Tip

Do not forget to copy the associated dynamic library file if you include a library in your code. For instance, if you include boost_system-mgw49-mt-1_58 using the –l option, you have to copy the libboost_system-mgw49-mt-1_58.dll file and paste it into the same directory as the output-executable file.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset