Get the FREE certificate on C, C++, Java, Python, Perl, PHP, SQL, Linux & Javascript!  

CppBuzz.com
  
Home C C++ Java Python Perl PHP Spring SQL Javascript Linux

You are here : Home » C++ 11 Multithreading Examples

C++ 11 Multithreading Examples

C++ 11 has introduced its own thread class which has functions related to multithreading

Creating Threads

This C++ code shows the basic program which create one thread and execute it

#include <iostream>
#include <thread> //header file required

void thread_func()
{
    std::cout << "thread function\n";
}

int main()
{
    std::thread t(&thread_func);   // t starts running
    std::cout << "this is main thread\n";
    t.join();   // <- main thread waits for the thread t to finish
	
    return 0;
}

This code will ouput (linux system):

thread function
this is main thread

Detaching Thread

We can make a new thread to run free to become a daemon process.
int main()
{
    std::thread t(&thread;_function);
    std::cout << "main thread\n";
    // t.join();
    t.detach();
    return 0;
}

The detached child thread is now free, and runs on its own. It becomes a daemon process.

main thread

Note that the detached thread didn't have a change to print its output to stdout because the main thread already finished and exited. This is one of the characteristics of multithreaded programming: we cannot be sure which thread runs first (not deterministic unless we use synchronization mechanism). In our case, because the time it takes to create a new thread, the main thread is most likely to finish ahead of our child thread.
One more thing we should note here is that even in this simple code we're sharing a common resource: std::cout. So, to make the code work properly, the main thread should allow our child thread to access the resource.
Once a thread detached, we cannot force it to join with the main thread again. So, the following line of the code is an error and the program will crash.

int main()
{
    std::thread t(&thread;_function);
    std::cout << "main thread\n";
    // t.join();
    t.detach();
    t.join();   // Error
    return 0;
}

Once detached, the thread should live that way forever.
We can keep the code from crashing by checking using joinable(). Because it's not joinable, the join() function won't be called, and the program runs without crash.

int main()
{
    std::thread t(&thread;_function);
    std::cout << "main thread\n";
    // t.join();
    if(t.joinable()) 
        t.join(); 
    return 0;
}

Passing Parameters to a thread

Here is an example of passing parameter to a thread. In this case, we're just passing a string:

#include <iostream>
#include <thread>
#include <string>

void thread_function(std::string s)
{
    std::cout << "thread function ";
    std::cout << "message is = " << s << std::endl;
}

int main()
{
    std::string s = "CppBuzz";
    std::thread t(&thread;_function, s);
    std::cout << "main thread message = " << s << std::endl;
    t.join();
    return 0;
}

From the following output, we know the string has been passed to the thread function successfully.

thread function message is = CppBuzz
main thread message = CppBuzz

If we want to pass the string as a ref, we may want to try this:


void thread_function(std::string &s)
{
    std::cout << "thread function ";
    std::cout << "message is = " << s << std::endl;
    s = "Chicago";
}

To make it sure that the string is really passed by reference, we modified the message at the end of the thread function. However, the output hasn't been changed.

thread function message is = CppBuzz
main thread message = CppBuzz

In fact, the message was passed by value not by reference. To pass the message by reference, we should modify the code a little bit like this using ref:


std::thread t(&thread;_function, std::ref(s));

Then, we get modified output:

thread function message is = CppBuzz
main thread message = Chicago

There is another way of passing the parameter without copying and not sharing memory between the threads. We can use move():


std::thread t(&thread;_function, std::move(s));

Since the string moved from main() to thread function, the output from main does not have it any more:

thread function message is = CppBuzz
main thread message =

Thread copy or move

Copying a thread won't compile:


#include <iostream>
#include <thread>

void thread_function()
{
    std::cout << "thread function\n";
}

int main()
{
    std::thread t(&thread;_function);
    std::cout << "main thread\n";
    std::thread t2 = t;

    t2.join();

    return 0;
}

But we can transfer the ownership of the thread by moving it:


#include <iostream>
#include <thread>

void thread_function()
{
    std::cout << "thread function\n";
}

int main()
{
    std::thread t(&thread;_function);
    std::cout << "main thread\n";
    std::thread t2 = move(t);

    t2.join();

    return 0;
}

Output:

main thread thread function

Thread id

We can get id information using this_thread::get_id():


int main()
{
    std::string s = "CppBuzz";
    std::thread t(&thread;_function, std::move(s));
    std::cout << "main thread message = " << s << std::endl;

    std::cout << "main thread id = " << std::this_thread::get_id() << std::endl;
    std::cout << "child thread id = " << t.get_id() << std::endl;

    t.join();
    return 0;
}

Output:

thread function message is = CppBuzz
main thread message =
main thread id = 1208
child thread id = 5224

How many threads?
The thread library provides the suggestion for the number of threads:


int main()
{
    std::cout << "Number of threads = " 
              <<  std::thread::hardware_concurrency() << std::endl;
    return 0;
}

Output:

Number of threads = 2