Creating a class to store threads and calling them - c++

Here is a simplified version of what I am trying to do:
#include <iostream>
#include <vector>
#include <thread>
#include <atomic>
class client {
private:
std::vector<std::thread> threads;
std::atomic<bool> running;
void main() {
while(running) {
std::cout << "main" << std::endl;
}
}
void render() {
while(running) {
std::cout << "render" << std::endl;
}
}
public:
client() {
running = true;
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));
}
~client() {
running = false;
for(auto& th : threads) th.join();
};
};
int main() {
client c;
std::string inputString;
getline(std::cin, inputString);
return 0;
}
(Note: code has been changed since question was written)
What I am trying to do is create a class that holds threads for the main loop(of the class), rendering, and a couple other things. However I cannot get this simplified version to work. I have tried using mutex to lock and unlock the threads, but didn't seem to help any. I do not know why it is not working, but I suspect that it is a result of the use of this in threads.push_back(std::thread(this->main, this));.
The current structure of the code doesn't have to remain... The only requirement is that uses one of it's own member functions as a thread (and that, that thread is stored in the class). I am not sure if this requires two classes or if my attempt to do it in one class was the correct approach. I have seen many examples of creating an object, and then calling a member that creates threads. I am trying to avoid this and instead create the threads within the constructor.

The problem here is that you do not wait for the threads to end. In main you create c. This then spawns the threads. The next thing to happen is to return which destroys c. When c is destroyed it destroys its members. Now when a thread is destroyed if it has not been joined or detached then std::terminate is called and the program ends
What you need to do is in the destructor, set running to false and then call join on both the threads. This will stop the loop in each thread and allow c to be destructed correctly.
Doing this however brings up another issue. running is not an atomic variable so writing to it while threads are reading it is undefined behavior. We can fin that though by changing running to a std::atomic<bool> which provides synchronization.
I also had to make a change to the thread construction. When you want to use a member function the syntax should be
std::thread(&class_name::function_name, pointer_to_instance_of_class_name, function_parameters)
so in this case it would be
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));

Related

Correct way to start a function object thread in C++?

I have this code so far :
#include <iostream>
#include <string>
#include <windows.h>
#include <iomanip>
#include <thread>
#include <chrono>
#include <atomic>
class test {
public:
thread t1;
test() : t1(&test::work, this) {
}
void work() {
while (true) {
cout << "in thread";
Sleep(1000);
}
}
};
int main()
{
test t;
while (true) {
cout << "in main" << endl;
Sleep(1000);
}
return 0;
}
Question 1: Is this how I'm suppose to create a thread in a class object for one function only after I initialize the object?
Question 2: I've seen people write atomic_bool and run(), is that necessary? and what is it for?
Question 3: do I need to delete or join the thread or do any kind of memory management?
Problem How can I create the thread somewhere else in the function of the objects other than the constructor? I have did this and it didn't work
void work() : t1(&test::work, this) {
while (true) {
cout << "in thread";
Sleep(1000);
}
}
Is this how I'm supposed to create a thread in a class object for one function only after I initialize the object?
It's one option. Another is t1([this]{ work(); }).
Relevant question: Start thread with member function
Be aware that, generally, the current instance (*this) may not be fully constructed when the thread starts executing.
I've seen people write atomic_bool and run(), is that necessary? and what is it for?
Don't know what run() is, but atomic variables are used for communication between threads via shared memory.
Do I need to delete or join the thread or do any kind of memory management?
No, you don't need any of these since your program never ends (at least normally).
How can I create the thread somewhere else in the function of the objects other than the constructor?
You can assign the thread member variable t1 a new value.
I would suggest reading some good book to learn such basics.

put another thread in sleep

i have a vector of objects std::vector and the fo object has a method start() where i create the thread specific to this object and now depends on a variable from this object i want to put it in sleep.
so for example if my object is f1 and the variable is bool sleep = false; when the sleep variable is true i want it to go to sleep.
i have tried this method but it doesn't seem to work. i think the if
class fo {
public :
thread* t ;
bool bedient = false , spazieren = false;
void start(){
t = new thread([this]() {
while (!this->bedient){
if (this->spazieren == true){
std::this_thread::sleep_for(std::chrono::seconds(10));
this->spazieren = false ;
}
}
this->join();
});
}
void join(){
t->join(); delete t;
}
};
You have "generated" a lot of problems on your code:
1)
Setting any kind of variable in one thread is potentially invisible in any other thread. If you want to make the other threads sees you changes in the first thread, you have to synchronize your memory. That can be done by using std::mutex with lock and unlock around every change of data or using std::atomic variables, which do the sync themselves or a lot of other methods. Please read a book about multi threaded programming!
2)
You try to join your own thread. That is not the correct usage at all. Any thread can join on others execution end but not on itself. That makes no sense!
3)
If you do not set manually the "sleep" var, your thread is running a loop and is simply doing nothing. A good method to heat up your core and the planet ;)
class fo {
public :
std::thread* t=nullptr ; // prevent corrupt delete if no start() called!
std::atomic<bool> bedient = false ;
std::atomic<bool> spazieren = false;
void start()
{
t = new std::thread([this]()
{
while (!this->bedient)
{
if (this->spazieren == true)
{
std::cout << "We are going to sleep" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
this->spazieren = false ;
}
}
std::cout << "End loop" << std::endl;
});
}
~fo() { delete t; }
void join()
{
std::cout << "wait for thread ends" << std::endl;
t->join();
}
};
int main()
{
fo f1;
f1.start();
sleep(1);
f1.spazieren = true;
sleep(1);
f1.bedient = true;
f1.join();
}
BTW:
Please do not use using namespace std!
Your design seems to be problematic. Setting vars from external threads to control execution of a thread is typically an abuse. You should think again for your design!
Manually using new/delete can be result in memory leaks.
Creating something with a start() method which later on will be deleted is mysterious. You should create all objects in the constructor.
I would try refactoring your code to use std::future instead of std::thread, furthermore there are a few issues which I believe you'll run into in the short term.
You shouldn't try to join while in the thread you're joining. That is, the code as you have it will never terminate. The lambda you've defined will attempt to call join, however, the lambda will never return since it's waiting on join which will only itself return when the lambda does so. In other words, you're telling it to wait on itself.
You're revealing too much information about the functionality of your class to the outside world. I would suggest moving implementation details into a .cc rather than putting it in the class declaration. Short of that, however, you're providing immediate access to your control variables spazieren and bedient. This is a problem because it complicates control flow and makes for weak abstraction.
Your bools are not atomic. If you attempt to modify them from outside the thread they're being read you'll run into crashes. And in some environments these crashes might be sporadic and very hard to debug.
Only sleeping when asked can be useful if you absolutely need to finish a task as soon as possible, but be aware that it's going to max out a core and if deployed to the wrong environment can cause major problems and slowdowns. I don't know what the end goal is for this program, but I would suggest considering changing the yield in the following code example to -some- period of time to sleep, 10 ms should be sufficient to prevent putting too much stress on your cpu.
Your threads status as to whether or not it's actively running is unclear with your implementation. I'd suggest considering an additional bool to indicate if it's running or not so you can more properly decide what to do if start() is called more than once.
When this object destructs it's going to crash if the thread is still running. You need to be sure to join before your destructor finishes running too.
I would consider the following refactorings:
#include <memory>
#include <future>
#include <atomic>
class fo
{
public:
~fo()
{
this->_bedient = true;
_workThread.wait();
}
void start()
{
_workThread = std::async(std::launch::async, [this]() -> bool
{
while(!this->_bedient)
{
if(true == this->_spazieren)
{
std::this_thread::sleep_for(std::chrono::seconds(10));
this->_spazieren = false;
}
else
{
std::this_thread::yield();
}
}
return true;
});
}
void ShouldSleep(bool shouldSleep)
{
this->_spazieren = shouldSleep;
}
void ShouldStop(bool shouldStop)
{
this->_bedient = !shouldStop;
}
private:
std::future<bool> _workThread = {};
std::atomic<bool> _bedient{ false };
std::atomic<bool> _spazieren{ false };
};

Initialising with std::call_once() in a multithreading environment [duplicate]

This question already has an answer here:
Is std::call_once a blocking call?
(1 answer)
Closed 3 years ago.
I'm reading the book C++ Concurrency in Action, 2nd Edition X. The book contains an example that uses the std::call_once() function template together with an std::once_flag object to provide some kind of lazy initialisation in thread-safe way.
Here a simplified excerpt from the book:
class X {
public:
X(const connection_details& details): connection_details_{details}
{}
void send_data(const data_packet& data) {
std::call_once(connection_init_, &X::open_connection, this);
connection_.send(data); // connection_ is used
}
data_packet receive_data() {
std::call_once(connection_init_, &X::open_connection, this);
return connection_.recv(data); // connection_ is used
}
private:
void open_connection() {
connection_.open(connection_details_); // connection_ is modified
}
connection_details connection_details_;
connection_handle connection_;
std::once_flag connection_init_;
};
What the code above does, is to delay the creation of the connection until the client wants to receive data or has data to send. The connection is created by the open_connection() private member function, not by the constructor of X. The constructor only saves the connection details to be able to create the connection at some later point.
The open_connection() member function above is called only once, so far so good. In a single-threaded context, this will work as expected. However, what if multiple threads are calling either the send_data() or the receive_data() member function on the same object?
Apparently, the modification/update of the connection_ data member in open_connection() is not synchronised with any of its uses in send_data() or receive_data().
Does std::call_once() block a second thread until the first one returns from std::call_once()?
XSection 3.3.1.: Protecting shared data during initialization
Based on this post I've created this answer.
I wanted to see whether std::call_once() synchronises with other calls to std::call_once() on the same std::once_flag object. The following program creates several threads that call a function that contains a call to std::call_once() that puts the calling thread to sleep for long time.
#include <mutex>
std::once_flag init_flag;
std::mutex mtx;
init_flag is the std::once_flag object to be used with the std::call_once() call. The mutex mtx is just for avoiding interleaved output on std::cout when streaming characters into std::cout from different threads.
The init() function is the one called by std::call_once(). It displays the text initialising..., puts the calling thread to sleep for three seconds and then displays the text done before returning:
#include <thread>
#include <chrono>
#include <iostream>
void init() {
{
std::lock_guard<std::mutex> lg(mtx);
std::cout << "initialising...";
}
std::this_thread::sleep_for(std::chrono::seconds{3});
{
std::lock_guard<std::mutex> lg(mtx);
std::cout << "done" << '\n';
}
}
The purpose of this function is to sleep for long enough (three seconds in this case), so that the remaining threads have enough time to reach the std::call_once() call. This way we will be able to see whether they block until the thread executing this function returns from it.
The function do_work() is called by all threads that are created in main():
void do_work() {
std::call_once(init_flag, init);
print_thread_id();
}
init() will be only called by one thread (i.e., it will be called only once). All threads call print_thread_id(), i.e., it is executed once for every thread created in main().
The print_thread_id() simply displays the current thread id:
void print_thread_id() {
std::lock_guard<std::mutex> lg(mtx);
std::cout << std::this_thread::get_id() << '\n';
}
A total of 16 threads, which call the do_work() function, are created in main():
#include <vector>
int main() {
std::vector<std::thread> threads(16);
for (auto& th: threads)
th = std::thread{do_work};
for (auto& th: threads)
th.join();
}
The output I get on my system is:
initialising...done
0x7000054a9000
0x700005738000
0x7000056b5000
0x700005632000
0x700005426000
0x70000552c000
0x7000055af000
0x7000057bb000
0x70000583e000
0x7000058c1000
0x7000059c7000
0x700005a4a000
0x700005944000
0x700005acd000
0x700005b50000
0x700005bd3000
This output means that no thread executes print_thread_id() until the first thread that called std::call_once() returns from it. This implies that those threads are blocked at the std::call_once() call.

Boost::thread how to get a pointer to the thread where my function is called?

With boost::thread how do I get a pointer to the boost::thread which is currently executing my function, from within that function?
The following does not compile for me:
boost::thread *currentThread = boost::this_thread;
You have to be careful because boost::thread is a movable type. Consider the following:
boost::thread
make_thread()
{
boost::thread thread([](boost::thread* p)
{
// here p points to the thread object we started from
}, &thread);
return thread;
}
// ...
boost::thread t = make_thread();
// if the thread is running by this point, p points to an non-existent object
A boost::thread object is conceptually associated to a thread but is not canonically associated to it, i.e. during the course of the thread more than one thread objects could have been associated with it (just not more than one at a given time). That's partly why boost::thread::id is here. So what is it you want to achieve exactly?
You can use boost::this_thread to reference the same thread you use it in.
See http://www.boost.org/doc/libs/1_41_0/doc/html/thread/thread_management.html
If you scour the Boost Thread documentation in its entirety (http://www.boost.org/doc/libs/release/doc/html/thread.html, or http://www.boost.org/doc/libs/1_60_0/doc/html/thread.html if that first link is broken), you'll find that there is no function provided to get a pointer to the boost::thread object that represents the current thread.
You can solve this problem on your own, however; one solution would be to use a map, mapping boost::thread:ids to boost:thread*s, and then access that map from within your thread to get the pointer.
For example:
#include <cstdio>
#include <map>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
std::map<boost::thread::id, boost::thread*> threadsMap;
boost::mutex threadsMapMutex; // to synchronize access to the map
boost::mutex stdoutMutex; // to synchronize access to stdout
void thread_function()
{
threadsMapMutex.lock();
// get a pointer to this thread
boost::thread::id id = boost::this_thread::get_id();
boost::thread* thisThread = threadsMap.find(id)->second;
threadsMapMutex.unlock();
// do whatever it is that you need to do with the pointer
if(thisThread != NULL)
{
stdoutMutex.lock();
printf("I have a pointer to my own thread!\n");
stdoutMutex.unlock();
}
}
int main()
{
threadsMapMutex.lock();
// create the threads
boost::thread thread1(&thread_function);
boost::thread thread2(&thread_function);
// insert the threads into the map
threadsMap.insert(std::pair<boost::thread::id, boost::thread*>(thread1.get_id(), &thread1));
threadsMap.insert(std::pair<boost::thread::id, boost::thread*>(thread2.get_id(), &thread2));
threadsMapMutex.unlock();
// join the threads
thread1.join();
thread2.join();
return 0;
}
P.S. I just noticed that you posted in a comment that you're actually using this solution, after having already written this. Oh well--I still find it useful and complete to officially post the answer to your question, as well as (working) sample code for a potential solution.
Instead of using additional map, it is possible to bind the created thread pointer to thread function directly. As #luc-danton mentioned, you must be sure that given pointer is valid as long as thread is alive.
E.g, when using boost::thread_group, interanlly threads are stored as raw pointers in the list, so thread pointer is valid all time.
void thread_func(boost::shared_future<boost::thread*> thread_ptr_future)
{
// Do not continue until this thread pointer is not set.
boost::thread* this_thread_ptr = thread_ptr_future.get();
std::cout << "This thread pointer gained: " << this_thread_ptr << std::endl;
//... continue thread content with valid this thread pointer.
}
boost::thread_group m_threads; ///< Instead of manually creating the list of threads.
void start_new_thread()
{
boost::promise<boost::thread*> thr_promise;
boost::shared_future<boost::thread*> thr_future(thr_promise.get_future());
boost::thread* thread_ptr =
m_threads.create_thread(boost::bind(thread_func, thr_future));
thr_promise.set_value(thread_ptr);
}

Simple example of threading in C++

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
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.
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.
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.
oneAPI Threading Building Blocks
Chapter 19. Thread (Boost documentation)
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;
}
#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);
}
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
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.
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.
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.