What exactly is join() in Boost::thread? (C++) - c++

In Java, I would do something like:
Thread t = new MyThread();
t.start();
I start thread by calling start() method. So later I can do something like:
for (int i = 0; i < limit; ++i)
{
Thread t = new MyThread();
t.start();
}
To create a group of threads and execute the code in run() method.
However, in C++, there's no such thing as start() method. Using Boost, if I want a thread to start running, I have to call the join() method in order to make a thread running.
#include <iostream>
#include <boost/thread.hpp>
class Worker
{
public:
Worker()
{
// the thread is not-a-thread until we call start()
}
void start(int N)
{
m_Thread = boost::thread(&Worker::processQueue, this, N);
}
void join()
{
m_Thread.join();
}
void processQueue(unsigned N)
{
float ms = N * 1e3;
boost::posix_time::milliseconds workTime(ms);
std::cout << "Worker: started, will work for "
<< ms << "ms"
<< std::endl;
// We're busy, honest!
boost::this_thread::sleep(workTime);
std::cout << "Worker: completed" << std::endl;
}
private:
boost::thread m_Thread;
};
int main(int argc, char* argv[])
{
std::cout << "main: startup" << std::endl;
Worker worker, w2, w3, w5;
worker.start(3);
w2.start(3);
w3.start(3);
w5.start(3);
worker.join();
w2.join();
w3.join();
w5.join();
for (int i = 0; i < 100; ++i)
{
Worker w;
w.start(3);
w.join();
}
//std::cout << "main: waiting for thread" << std::endl;
std::cout << "main: done" << std::endl;
return 0;
}
On the code above, the for loop to create 100 threads, normally I must use a boost::thread_group to add the thread function, and finally run all with join_all(). However, I don't know how to do it with thread function putting in a class which uses various class members.
On the other hand, the loop above will not behave like the loop in Java. It will make each thread execute sequentially, not all at once like the other separated threads, whose own join() is called.
What is join() in Boost exactly? Also please help me to create a group of threads which share the same class.

join doesn't start the thread, it blocks you until the thread you're joining finishes. You use it when you need to wait for the thread you started to finish its run (for example - if it computes something and you need the result).
What starts the thread is boost::thread, which creates the thread and calls the thread function you passed to it (in your case - Worker::processQueue).
The reason you had a problem with the loop is not because the threads didn't start, but because your main thread didn't wait for them to execute before finishing. I'm guessing you didn't see this problem in Java because of the scheduling differences, aka "undefined behavior". after edit In Java the threading behaves slightly differently, see the comment below for details. That explains why you didn't see it in Java.
Here's a question about the boost::thread_group. Read the code in the question and the answers, it will help you.

Joining a thread does the same thing in Boost as it does in Java: it waits for the thread to finish running.
Plus, if I remember correctly, Boost's threads run upon construction. You don't start them explicitly.

Related

Using boost to turn single thread to multi thread

I'm trying to turn a code from a single thread to a multi thread(example, create 6 threads instead of 1) while making sure they all start and finish without any interference from each other. What would be a way to do this? Could I just do a for loop that creates a thread until i < 6? And just add a mutex class with lock() and unlock()?
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
void workerFunc()
{
boost::posix_time::seconds workTime(3);
std::cout << "Worker: running" << std::endl;
// Pretend to do something useful...
boost::this_thread::sleep(workTime);
std::cout << "Worker: finished" << std::endl;
}
int main(int argc, char* argv[])
{
std::cout << "main: startup" << std::endl;
boost::thread workerThread(workerFunc);
std::cout << "main: waiting for thread" << std::endl;
workerThread.join();
std::cout << "main: done" << std::endl;
system("pause");
return 0;
}
Yes, it's certainly possible. Since you don't want any interference between them, give them unique data to work with so that you do not need to synchronize the access to that data with a std::mutex or making it std::atomic. To further minimize the interference between threads, align the data according to std::hardware_destructive_interference_size.
You can use boost::thread::hardware_concurrency() to get the number of hardware threads available on the current system so that you don't have to hardcode the number of threads to run.
Passing references to the thread can be done using std::ref (or else the thread will get a ref to a copy of the data).
Here I create a std::list of threads and a std::vector of data to work on.
#include <cstdint> // std::int64_t
#include <iostream>
#include <list>
#include <new> // std::hardware_destructive_interference_size
#include <vector>
#include <boost/thread.hpp>
unsigned hardware_concurrency() {
unsigned rv = boost::thread::hardware_concurrency();
if(rv == 0) rv = 1; // fallback if hardware_concurrency returned 0
return rv;
}
// if you don't have hardware_destructive_interference_size, use something like this
// instead:
//struct alignas(64) data {
struct alignas(std::hardware_destructive_interference_size) data {
std::int64_t x;
};
void workerFunc(data& d) {
// work on the supplied data
for(int i = 0; i < 1024*1024-1; ++i) d.x -= i;
for(int i = 0; i < 1024*1024*1024-1; ++i) d.x += i;
}
int main() {
std::cout << "main: startup" << std::endl;
size_t number_of_threads = hardware_concurrency();
std::list<boost::thread> threads;
std::vector<data> dataset(number_of_threads);
// create the threads
for(size_t idx = 0; idx < number_of_threads; ++idx)
threads.emplace_back(workerFunc, std::ref(dataset[idx]));
std::cout << "main: waiting for threads" << std::endl;
// join all threads
for(auto& th : threads) th.join();
// display results
for(const data& d : dataset) std::cout << d.x << "\n";
std::cout << "main: done" << std::endl;
}
If you are using C++11 (or later), I suggest using std::thread instead.
Starting and stopping a bunch of Boost threads
std::vector<boost::thread> threads;
for (int i = 0; i < numberOfThreads; ++i) {
boost::thread t(workerFunc);
threads.push_back(std::move(t));
}
for (auto& t : threads) {
t.join();
}
Keep in mind that join() doesn't terminate the threads, it only waits until they are finished.
Synchronization
Mutexes are required if multiple threads access the same data and at least one of them is writing the data. You can use a mutex to ensure that multiple threads enter the critical sections of the code. Example:
std::queue<int> q;
std::mutex q_mu;
void workerFunc1() {
// ...
{
std::lock_guard<std::mutex> guard(q_mu);
q.push(foo);
} // lock guard goes out of scope and automatically unlocks q_mu
// ...
}
void workerFunc2() {
// ...
{
std::lock_guard<std::mutex> guard(q_mu);
foo = q.pop();
} // lock guard goes out of scope and automatically unlocks q_mu
// ...
}
This prevents undefined behavior like reading an item from the queue that hasn't been written completely. Be careful - data races can crash your program or corrupt your data. I'm frequently using tools like Thread Sanitizer or Helgrind to ensure I didn't miss anything. If you only want to pass results back into the main program but don't need to share data between your threads you might want to consider using std::promise and std::future.
Yes, spawning new threads can be done with a simple loop. You will have to keep a few things in mind though:
If threads will operate on shared data, it will need to be protected with mutexes, atomics or via some other way to avoid data races and undefined behaviour (bear in mind that even primitive types such as int have to be wrapped with an atomic or mutex according to the standard).
You will have to make sure that you will eventually either call join() or detach() on every spawned thread before its object goes out of scope to prevent it from suddenly terminating.
Its best to do some computations on the main thread while waiting for worker threads to use this time efficiently instead of wasting it.
You generally want to spawn 1 thread less than the number of total threads you want as the program starts running with with one thread by default (the main thread).

Execute callback function on main thread from std::thread

I have a requirement of executing a callback function on exit of a std::thread and the callback function should be executed on the main thread.
On thread creation I need to detach the thread and cannot block the main loop execution for thread completion.
i tried using std::signal but that does not seem to execute callback function on the main thread
#include <thread>
#include <csignal>
#include <iostream>
std::thread::id main_thread_id;
void func2()
{
for(int i = 0; i < 10000000; i++)
{
// do something
}
}
void func()
{
for(int i = 0; i < 10; i++)
{
func2();
}
std::raise(SIGUSR1);
}
void callback(int signal)
{
std::cout << "SIGNAL: " << signal << " THREAD ID:" <<
std::this_thread::get_id() << std::endl;
bool b = std::this_thread::get_id() == main_thread_id;
std::cout << "IS EXECUTED ON MAIN THREAD: " << b << std::endl;
}
int main()
{
main_thread_id = std::this_thread::get_id();
std::cout << "MAIN THREAD ID: " << std::this_thread::get_id() << std::endl;
std::signal(SIGUSR1, callback);
std::thread t1(func);
t1.detach();
for(int i = 0; i < 20; i++)
{
func2();
}
if(t1.joinable())
t1.join();
}
The result I get is that the callback function is not executed on main thread. Please suggest a way in which I can create a worker thread and call a callback function on main thread upon exit of the thread.
Thanks for the help
There are a few ways to do this.
First, your main thread could be running a message loop. In which case, you queue up a message with a payload that tells the main thread to run some code (either carry the code to run via a pointer part of the message to the main thread, or put it in some known spot that the main thread checks).
A second approach is to return something like a std::future<std::function<void()>> object, and the main thread checks if the future is ready. When it is ready, it runs the code.
A third approach is to create a concurrent queue that the main thread waits on, and stuff your message (containing code to run) onto that queue.
All of these things require the active cooperation of the main thread. The main thread cannot be preemted and told to run different code without its cooperation.
Which is best depends on features of your program you did not choose to mention in your question. If you are a graphical GUI with a message loop, use the message loop. If you are a streaming processor that paralellizes some work, and you don't need prompt execution, yet eventually will want to block on the parallel work, a future might be best. If you are a message passing channel-type app, a set of queues might be best.

Mutex & Threads: Explanation

I have been reading over the following tutorial: C++ Multithreading Tutorial.
I have compiled the code in the tutorial that creates ten unique threads and print a string with the thread number.
Here is what the code looks like for those who don't want to open the link:
#include <iostream>
#include <thread>
static const int num_threads = 10;
//This function will be called from a thread
void call_from_thread(int tid) {
std::cout << "Launched by thread " << tid << std::endl;
}
int main() {
std::thread t[num_threads];
//Launch a group of threads
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
std::cout << "Launched from the main\n";
//Join the threads with the main thread
for (int i = 0; i < num_threads; ++i) {
t[i].join();
}
return 0;
}
When I run the code it compiles and the output is kind of random.
It will launch each thread but it won't launch them in order.
I was reading the C++ reference on std::mutex and it sounds like that is what I need.
So, I was wondering if someone could give me a quick rundown over how to implement std:mutex in code like this to ensure that the threads don't use the same shared resource and to ensure that they launch in order.
The threads are created in the right order, but the order of scheduling of their execution is not guaranteed to be the same.
Is mutex the solution ?
You could attempt to add a mutex. This will only assure that two threads are not in the critical section at the same time:
std::mutex mtx;
void call_from_thread(int tid) {
std::lock_guard<std::mutex> lock(mtx); // holds the lock until scope is left
std::cout << "Launched by thread " << tid << std::endl;
}
Note tha I didn't lock the mutex directly and I prefered the lock_guard: this locks the mutex using RAII which is exception safe.
Online demo 1
Is atomic the solution
Another way to do multithreading without mutex, is to use atomic variables. These are guaranteed to be accessed by one thread at a time without data race.
std::atomic<int> cnt{0};
void call_from_thread(int tid) {
while (cnt!=tid)
std::this_thread::yield();
std::cout << "Launched by thread " << tid << std::endl;
cnt++;
}
Of course the code above is useless: it just makes sure that threads are executed in sequence. Every thread looks it the global atomic counter corresponds to its number. if yes, it executes and increments the global counter. If not, it just gives the opportunity to another thread to execute.
Online demo 2
Of course this construct here is a waste of time. Normally, you'd use condition variables to do something like this. it's only for illustration.
Conclusion
Multithreading is quite complex. If you want to dig into it, I highly recommend Anthony William's book "C++ Concurrency in action", which is an excellent step by step introduction, not only to C++ multithreading libraries, but more generally challenges of multithreaded algorithms.

boos::asio async_wait seems to be blocking

I was learning boost asio documentation.I came across this deadline_timer example.
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
/*This timer example shows a timer that fires once every second.*/
void print(const boost::system::error_code& e, boost::asio::deadline_timer* t, int* count)
{
if (*count < 5)
{
std::cout << *count << std::endl;
++(*count);
t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
t->async_wait(boost::bind(print,boost::asio::placeholders::error, t, count));
}
}
int main()
{
boost::asio::io_service io;
int count = 0;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
auto myfunc = boost::bind(print, boost::asio::placeholders::error, &t ,&count);
t.async_wait(myfunc);
std::cout << "async wait " << std::endl;
io.run();
std::cout << "Just called io.run() " << std::endl;
std::cout << "Final count is " << count << std::endl;
return 0;
}
The async_wait() function seems to be blocking (i.e waiting for the 10 second timer to expire)
The output from the above program is as follows.
async wait
0
1
2
3
4
Just called io.run()
Final count is 5
I would expect an async_wait() to create a separate thread and wait for the timer to expire there meanwhile executing the main thread.
i.e I would expect the program to print
Just called io.run()
Final count is 5
while waiting for the timer to expire.? Is my understanding wrong?
This is my understanding of async_wait(). This implementation looks more like a blocking wait. Is my understanding wrong? What am I missing?
The io.run(); statement is the key to explaining the difference between the output you're getting and the output you're expecting.
In the ASIO framework, any asynchronous commands need to have a dedicated thread to run the callbacks upon. But because ASIO is relatively low-level, it expects you to provide the thread yourself.
As a result, what you're doing when you call io.run(); within the main thread is to specify to the framework that you intend to run all asynchronous commands on the main thread. That's acceptable, but that also means that the program will block on io.run();.
If you intend the commands to run on a separate thread, you'll have to write something like this:
std::thread run_thread([&]() {
io.run();
});
std::cout << "Just called io.run() " << std::endl;
std::cout << "Final count is " << count << std::endl;
run_thread.join();
return 0;
The async_wait function isn't blocking, run is. That's run's job. If you don't want a thread to block in the io_service's processing loop, don't have that thread call run.
The async_wait function doesn't create any threads. That would make it expensive and make it much harder to control the number of threads servicing the io_service.
Your expectation is unreasonable because returning from main terminates the process. So who or what would wait for the timer?

Why does the main thread crash in this C++ sample snippet using <thread>?

I am beginning to use the thread class.
In the main() thread below, an Example class is created.
Inside the constructor of Example, two threads are created in the Example::start() function.
Example::foo() is designed to print a message every second.
Example::bar() is designed to print a message every 5 seconds.
Inside the main() function, a loop is designed to print every 3 seconds.
I decided to not use join() in Example::start() because I would like to have the main() function continuously run.
Why does the main thread crash during run-time?
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
using namespace std;
class Example
{
public:
Example();
void start();
void foo();
void bar(int x);
};
Example::Example()
{
start();
}
void Example::start()
{
std::thread first (&Example::foo, this); // spawn new thread that calls foo()
std::thread second (&Example::bar, this, 5); // spawn new thread that calls bar(0)
// synchronize threads:
//first.join(); // pauses until first finishes
//second.join(); // pauses until second finishes
}
void Example::foo()
{
cout << "entered foo()" << endl;
int count = 0;
while(1) {
std::this_thread::sleep_for (std::chrono::seconds(1));
++count;
cout << "foo() count = " << count << endl;
}
}
void Example::bar(int x)
{
cout << "entered bar() x = " << x << endl;
int count = 0;
while(1) {
std::this_thread::sleep_for (std::chrono::seconds(5));
++count;
cout << "bar() count = " << count << endl;
}
}
int main() {
Example* c = new Example();
cout << "Example() created" << endl;
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(3));
cout << "main() thread loop..." << endl;
}
std::cout << "end of main()";
delete c;
return 0;
}
Foo::Start() initalizes two threads, thread Foo and thread bar. When the function Start returns to the main thread, the two thread objects go out of scope and the destructor is called for clearing out of scope variables.
A simple solution would be to make threads part of the class.
On another note, std::cout is not a synchronized class, when writing your text might be garbled: Is cout synchronized/thread-safe?
Also, when creating your class Example, delete is never called which causes a memory leak.
Your comment here:
void Example::start()
{
std::thread first (&Example::foo, this); // spawn new thread that calls foo()
std::thread second (&Example::bar, this, 5); // spawn new thread that calls bar(0)
// synchronize threads:
//first.join(); // pauses until first finishes
//second.join(); // pauses until second finishes
}
Is wrong.
Not only does the the join pause until the threads finish. But they also allow the thread to be cleaned up. A thread destructor calls terminate while the thread is join-able (ie it is still running). So you must call join() on the thread (to wait for it to finish) before you can allow the destructor to be called.
One of the comments above suggests calling detach(). This detaches the thread of execution from the thread object (thus making it not join-able). This will work (as your code is in infinite loop), but is a bad idea generally. As allowing main() to exit while threads are still running is undefined behavior.