Simple example of threading in C++

C++Multithreading

C++ Problem Overview


Can someone post a simple example of starting two (Object Oriented) threads in C++.

I'm looking for actual C++ thread objects that I can extend run methods on (or something similar) as opposed to calling a C-style thread library.

I left out any OS specific requests in the hopes that whoever replied would reply with cross platform libraries to use. I'm just making that explicit now.

C++ Solutions


Solution 1 - C++

Create a function that you want the thread to execute, for example:

void task1(std::string msg)
{
    std::cout << "task1 says: " << msg;
}

Now create the thread object that will ultimately invoke the function above like so:

std::thread t1(task1, "Hello");

(You need to #include <thread> to access the std::thread class.)

The constructor's first argument is the function the thread will execute, followed by the function's parameters. The thread is automatically started upon construction.

If later on you want to wait for the thread to be done executing the function, call:

t1.join();

(Joining means that the thread who invoked the new thread will wait for the new thread to finish execution, before it will continue its own execution.)


The Code

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

using namespace std;

// The function we want to execute on the new thread.
void task1(string msg)
{
    cout << "task1 says: " << msg;
}

int main()
{
    // Constructs the new thread and runs it. Does not block execution.
    thread t1(task1, "Hello");

    // Do other things...

    // Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
    t1.join();
}

More information about std::thread here

  • On GCC, compile with -std=c++0x -pthread.

  • This should work for any operating-system, granted your compiler supports this (C++11) feature.

Solution 2 - C++

Well, technically any such object will wind up being built over a C-style thread library because C++ only just specified a stock std::thread model in C++0x, which was just nailed down and hasn't yet been implemented.

The problem is somewhat systemic. Technically the existing C++ memory model isn't strict enough to allow for well-defined semantics for all of the 'happens before' cases. Hans Boehm wrote an paper on the topic a while back and was instrumental in hammering out the C++0x standard on the topic.

Threads Cannot be Implemented as a Library

That said, there are several cross-platform thread C++ libraries that work just fine in practice. The Intel thread building blocks contains a tbb::thread object that closely approximates the C++0x standard and Boost has a boost::thread library that does the same.

Using boost::thread, you'd get something like:

#include <boost/thread.hpp>

void task1() {
    // do stuff
}

void task2() {
    // do stuff
}

int main (int argc, char ** argv) {
    using namespace boost;
    thread thread_1 = thread(task1);
    thread thread_2 = thread(task2);

    // do other stuff
    thread_2.join();
    thread_1.join();
    return 0;
}

Solution 3 - C++

#include <thread>
#include <iostream>
#include <vector>
using namespace std;

void doSomething(int id) {
	cout << id << "\n";
}

/**
 * Spawns n threads
 */
void spawnThreads(int n)
{
	std::vector<thread> threads(n);
	// spawn n threads:
	for (int i = 0; i < n; i++) {
		threads[i] = thread(doSomething, i + 1);
	}

	for (auto& th : threads) {
		th.join();
	}
}

int main()
{
	spawnThreads(10);
}

Solution 4 - C++

There is also a POSIX library for POSIX operating systems.

Check for compatibility:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>

void *task(void *argument){
    char* msg;
    msg = (char*)argument;
    std::cout << msg << std::endl;
}

int main(){
    pthread_t thread1, thread2;
    int i1, i2;
    i1 = pthread_create(&thread1, NULL, task, (void*) "thread 1");
    i2 = pthread_create(&thread2, NULL, task, (void*) "thread 2");

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

Compile with -lpthread.

POSIX Threads

Solution 5 - C++

When searching for an example of a C++ class that calls one of its own instance methods in a new thread, this question comes up, but we were not able to use any of these answers that way. Here's an example that does that:

Class.h

class DataManager
{
public:
    bool hasData;
    void getData();
    bool dataAvailable();
};

Class.cpp

#include "DataManager.h"

void DataManager::getData()
{
    // perform background data munging
    hasData = true;
    // be sure to notify on the main thread
}

bool DataManager::dataAvailable()
{
    if (hasData)
    {
        return true;
    }
    else
    {
        std::thread t(&DataManager::getData, this);
        t.detach(); // as opposed to .join, which runs on the current thread
    }
}

Note that this example doesn't get into mutex or locking.

Solution 6 - C++

Unless one wants a separate function in the global namespace, we can use lambda functions for creating threads.

One of the major advantage of creating a thread using lambda is that we don't need to pass local parameters as an argument list. We can use the capture list for the same and the closure property of lambda will take care of the lifecycle.

Here is sample code:

int main() {
    int localVariable = 100;

    thread th { [=]() {
        cout << "The value of local variable => " << localVariable << endl;
    }};

    th.join();

    return 0;
}

By far, I've found C++ lambdas to be the best way of creating threads especially for simpler thread functions.

Solution 7 - C++

It largely depends on the library you decide to use. For instance, if you use the wxWidgets library, the creation of a thread would look like this:

class RThread : public wxThread {

public:
    RThread()
        : wxThread(wxTHREAD_JOINABLE){
    }
private:
    RThread(const RThread &copy);

public:
    void *Entry(void){
        //Do...

        return 0;
    }

};

wxThread *CreateThread() {
    //Create thread
    wxThread *_hThread = new RThread();

    //Start thread
    _hThread->Create();
    _hThread->Run();

    return _hThread;
}

If your main thread calls the CreateThread method, you'll create a new thread that will start executing the code in your "Entry" method. You'll have to keep a reference to the thread in most cases to join or stop it.

More information is in the wxThread documentation.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZakView Question on Stackoverflow
Solution 1 - C++MasterMasticView Answer on Stackoverflow
Solution 2 - C++Edward KmettView Answer on Stackoverflow
Solution 3 - C++CanerView Answer on Stackoverflow
Solution 4 - C++HohenheimsenbergView Answer on Stackoverflow
Solution 5 - C++livingtechView Answer on Stackoverflow
Solution 6 - C++Deepak Kr GuptaView Answer on Stackoverflow
Solution 7 - C++LorenzCKView Answer on Stackoverflow