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.
Related
I am learning C++ threads and i don't understand unique_lock mechanism very well. I reed This Link with Conditional variable, and more examples here but still I have my confusions:
1- So my question clearly is, doesn't unique_lock protect the mutual exclusion? I see in some examples when we use it on a shared mutex, the second thread cannot enter to that area which what I expect. But in this example as you see the output, all the threads can pass this line: std::unique_lockstd::mutex lck(mtx); is it just declaration or mutex gets locked as it declared?
2- why does the .lock() cause abort error? If I comment out that line all the threads starts in a row as you see in the screen shot output. I expect only thread0 pass the std::unique_lock<std::mutex> lck(mtx); it should be locked for other threads
Thanks
#include <mutex>
using namespace std;
condition_variable cv;
bool ready = false;
mutex mtx;
void print_id(int id) {
// why all the threads can pass this line?
std::unique_lock<std::mutex> lck(mtx);
//i knew about the concept of two times locking, just thought there
//is something wrong with the constructor or i dont understand
lck.lock(); // Having this line gives me abort.
std::cout << "thread Starts: " << id << '\n';
while (!ready)
cv.wait(lck);
// ...
std::cout << "thread Ends: " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
void main()
{
std::thread threads[5];
// spawn 10 threads:
for (int i = 0; i < 5; ++i)
{
this_thread::sleep_for(chrono::milliseconds(2000));
threads[i] = std::thread(print_id, i);
}
std::cout << "10 threads ready to race...\n";
go(); // go!
for (auto& th : threads) th.join();
}
std::unique_lock is an RAII type. When an object of that type is constructed, it locks the mutex that was passed to it, and upon destruction it unlocks the mutex, so you have scope level locking and unlocking.
All that means is that when you do lck.lock(); you are trying to lock a mutex you have already locked by creating lck. std::unique_lock::lock() will throw an exception when you do this, and it is that uncaught exception that is causing abort() to be called.
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).
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.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm pretty new to C++ and I'm experimenting with threads right now.
I'm trying to create a thread inside a thread under a while loop. But I don't think it seems to be working.
Presently my code looks like this:
#include <>
std::vector<pthread_t> outer_thread, inner_thread;
void *inner_thread(void *ptr)
{
string data1;
data1 = *(reinterpret_cast<string*>(ptr));
cout << "inner thread started " << data1;
/* do something */
cout << "inner thread stopped " << data1;
pthread_exit(NULL);
return 0;
}
void *outer_thread(void *ptr )
{
cout << "out thread started" << endl;
//cout << ptr << endl;
//cout << *(reinterpret_cast<string*>(ptr)) << endl;
string data;
data = *(reinterpret_cast<string*>(ptr));
string str3;
while (getline(data,str3))
{
cout << "out thread started" << endl;
pthread_t in_thread;
in_vec.push_back(str3);
int create_thread2 = pthread_create(&in_thread, NULL, &inner_thread, reinterpret_cast<void*>(&(in_vec.at(j))));
inner_thread.push_back(in_thread);
if (create_thread2 != 0)
cout << "Error : Thread";
j++;
cout << "out thread ends " << j << create_thread2 << endl ;
}
for (int k = 0; k < j ; k++)
{
pthread_join(inner_thread.at(k),NULL) ;
}
pthread_exit(NULL);
return 0;
}
int main (int argc, char *argv[])
{
int i = 0;
while (getline(gin,str))
{
string str1;
pthread_t out_thread;
cout << "str1" << str1 << endl;
now_vec.push_back(str1);
int create_thread = pthread_create(&out_thread, NULL, &outer_thread, reinterpret_cast<void*>(&(now_vec.at(i))));
outer_thread.push_back(out_thread);
if (create_thread != 0) cout << "Error : Thread" ;
i++;
}
for (int k = 0 ; k < i; k ++)
{
cout << i << endl;
//cout << "third thread " << outer_thread.at(1) << endl;
cout << outer_thread.at(k) << endl;
cout << "out out out" << endl;
pthread_join(outer_thread.at(k),NULL) ;
}
}
I'm trying to read a file which contains the list of files that should be read. I want to read all these files simultaneously.
All these files contain information and needs another set of threads to start another operation. So this also needs to be done simultaneously.
That's the reason I have 2 sets of threads running.
Let me know If there is any faster and simpler way to do this?
It seems to wait till the inner thread finishes and then starts with the next iteration. I want the inner threads to run simultaneously inside the outer thread. May I know how to go about this?
Your view of the operation of threads is wrong. A thread does not operate within another thread. They are independent streams of execution within the same process and their coexistence is flat, not hierarchical.
Some simple rules to follow when working with multiple threads:
Creating threads is expensive, so avoid creating and destroying them rapidly. It is best to create your threads once at the start of your application and assign them work to do as work becomes available.
When doing computational work, avoid creating more threads than can simultaneously execute on your CPU. Any additional threads will cause excess context switches and slow down your application.
Avoid the use of shared resources as often as possible, if a data structure must be shared between threads try and find a lock free implementation. If your shared resource is not available in a lock free implementation then use locks to protect it, but be very careful, improper use of locks can result in your application deadlocked or the performance of you application degrading to the serial execution case (as if there was only one thread).
In your particular case, if you want to speed up the processing of multiple files by processing them in parallel (and assuming the only task these threads need to achieve is the processing of these files), then a possible solution would look like:
Read in the list of files to operate on
Divide the list into sections (one section for each logical processor on you CPU).
Create your worker threads (one per logical processor) passing in their section of the file list (do not try to join with the thread in the same loop that creates it, this will block until the thread has finished executing causing your application to execute serially instead of in parallel, which is the case in the sample code you provided)
The worker threads can loop over their list of files, reading them one at a time and processing them.
In contrast to you proposed solution this one will not create a thread per file. Instead it will create as many threads as can run in parallel on your CPU avoiding the excessive context switching.
A primitive example of the above:
#include <pthread.h>
#include <vector>
#include <string>
#define NUM_THREADS 4
std::vector<std::string> work_pool[NUM_THREADS];
void *worker_thread(void *args);
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
// Read list of files here, distribute them evenly amongst the work_pools
for (int i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, worker_thread, (void *)i);
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
void *worker_thread(void *args)
{
const int id = (int)args;
std::vector<std::string>::iterator it;
for (it = work_pool[id].begin(); it != work_pool[id].end(); it++) {
// Read file and process it here
}
return NULL;
}
Not sure what you're trying to do, but among the many syntax errors that I hope come from simplying your code, this is what happens:
Main thread spawns a thread (1) and wait for it to finish (join)
(1) thread executes outer_thread and spawns another thread (2) and wait for it to finish (join)
(2) thread executes inner_thread and finish.
(2) gets joined and (1) thread is able to finish.
(1) gets joined and the main thread is able to go to the next iteration.
process starts again.
Note that you don't have any parallel execution, because your threads are waiting for other finish.
Note that throwing threads at a task is not the way to speed up.
Threads are a way of either:
Better using your CPU resources (when you have multiple CPU resources... and only using as many threads as CPU resources you have)
Simplifying the organization of your code by encapsulating requests as threads (but this kind of trick scale very badly)
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.