Channels ▼

Mark Nelson

Dr. Dobb's Bloggers

C++11's async Template

May 30, 2012

When To Use async

In his C++11 FAQ, Bjarne Stroustroup has this to say about async:

...don't even think of using async() to launch tasks that do I/O, manipulate mutexes, or in other ways interact with other tasks. The idea behind async() is the same as the idea behind the range-for statement: Provide a simple way to handle the simplest, rather common, case and leave the more complex examples to the fully general mechanism.

I'm not sure I agree with this disclaimer. The async function is in no way a second-class citizen when it comes to launching threads. It simply lowers the barriers to using threads by providing a very nice mechanism for launching them and retrieving their return values.

You can see that in my example I use a mutex to guard access to a data structure. This is not made more dangerous by using async to launch my thread — I use the mutex exactly as I would if I had launched my threads using the thread class.

If your compiler supports async, I say use it!

Does Your Compiler Support async?

No doubt these new C++11 features are quite cool, but in order to use them, your compiler has to support them. Does yours?

It's a little hard to read the status of async by browsing the g++ or the Visual C++ 11 beta charts. Regardless of what they may say, this program does build and run properly with g++ 4.7 and the Visual C++ 11 beta.

Updating to g++ 4.7 on your Linux system can be somewhat tricky. Ideally, you would like to find a prebuilt version of the compiler that will work with your distribution. As an example, I was able to easily update my Ubuntu system with the instructions found here. Visual C++ 11 is here. Visual C++ 11 is available to all for free - installing alongside other versions of Vis>available to all for free — installing alongside other versions of Visual C++ seems to work fine.

A little extra work maybe, but really, you shoulder be knee-deep in C++11 by now. This is modern C++.

WordSearch.cpp Source

You can download a copy of sowpods.txt here. The full source for WordSearch.cpp is here:

// WordSearch.cpp
// When building with g++ 4.7 or later, use this command line:
//  g++ -pthread --std=c++0x 
#include <fstream>
#include <iostream>
#include <string>
#include <deque>
#include <vector>
#include <future>
#include <mutex>
#include <functional>

using namespace std;

std::mutex m;

inline bool match( const std::string &pattern, std::string word )
    if ( pattern.size() != word.size() )
        return false;
    for ( size_t i = 0 ; i < pattern.size() ; i++ ) 
        if ( pattern[ i ] != '.' && pattern[ i ] != word[ i ] )
            return false;
    return true;

vector<string> find_matches( string pattern, deque<string> &backlog )
    vector<string> results;
    for ( ; ; ) {
        if ( backlog.size() == 0 ) {
            return results;
        string word = backlog.front();
        if ( match( pattern, word ) )
            results.push_back( word );

template<class ASYNC>
void print_results( ASYNC &f, string &pattern, int threadno )
    vector<string> words = f.get();
    cerr << "Found " << words.size() 
         << " matches for " << pattern 
         << " in thread " << threadno
         << endl;
    for ( auto s : words )
        cout << s << "\n";

int main( int argc, char *argv[] )
    if ( argc < 2 ) {
        cerr << "Usage: WordSearch match-expression\n\n"
                "match-expression contains lower case letters and periods.\n"
                "The periods will match any character\n";
        return -1;
    string pattern = argv[ 1 ];
    // Load the words into the deque
    ifstream f( "sowpods.txt" );
    if ( !f ) {
        cerr << "Cannot open sowpods.txt in the current directory\n";
        return -1;
    string word;
    deque<string> backlog;
    while ( f >> word )
        backlog.push_back( word );
    // Now process the words and print the results
    auto f1 = async( launch::async, find_matches, pattern, ref(backlog) );
    auto f2 = async( launch::async, find_matches, pattern, ref(backlog) );
    auto f3 = async( launch::async, find_matches, pattern, ref(backlog) );
    print_results( f1, pattern, 1 );
    print_results( f2, pattern, 2 );
    print_results( f3, pattern, 3 );

    return 0;

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.