Vector of thread pointers, push_back causes crash - c++

I am new to C++, and I was lately looking into concurrency.
I tried to run this simple program demonstrating threads:
#include <vector>
#include <thread>
#include <stdio.h>
void threadWork()
{
printf("WORKER THREAD EXECUTING");
}
int main()
{
printf("INSTANTIATE THREAD\n");
std::vector<std::thread *> threadList;
threadList.push_back(&std::thread(&threadWork));
printf("THREAD INSTANTIATED JOINING...\n");
for (std::thread* t : threadList)
{
t->join();
}
printf("THREADS JOINED\n");
return 0;
}
After the call to push_back() the program crashes with a call to abort() (I am running this on Windows)
Why is this code crashing at runtime?

std::vector<std::thread *> threadList;
threadList.push_back(&std::thread(&threadWork));
Here you take the address of a temporary.
This is not permitted in C++, but Visual Studio lets you do it anyway.
That's a shame because the temporary is destroyed at the end of the call, so your vector contains nothing but a dangling pointer.
Furthermore, since you are not join()ing or detach()ing the thread, destroying its std::thread (which happens when it goes out of scope) causes your program to std::terminate() (commonly considered a crash).
I recommend re-reading the chapter in your C++ book about thread management, so that you can be assured of effecting it in a safe manner.
Forget about pointers here; you don't need them. Instead, just have a nice simple vector of threads, and directly construct your elements using emplace_back, like this:
std::vector<std::thread> threadList;
threadList.emplace_back(&threadWork);
Then ensure you join() your threads before program completion.

The program aborts because std thread aborts if you destroy it when it is running or finished.
This happens because you are storing a vector of pointers and taking the address of temporary objects. The first is a bad idea, the second is illegal in C++ but MSVC permits it by default.
In C++ you should default to using values, especially with std library types. And when you don't use values, use smart pointers. Using raw pointer should usually be either only for some function args, sometimes in a struct/class with reference semantics, or when doing C interop.
So here,
std::vector<std::thread> threadList;
is a vector of threads. No pointless pointers.
threadList.emplace_back(&threadWork);
that creates a new thread running threadwork/
for(auto& thread:threadList){
thread.join();
}
that joins the threads; this will wait until the thread is done. Failure to do something like this will make your program abort.
All together:
printf("INSTANTIATE THREAD\n");
std::vector<std::thread> threadList;
threadList.emplace_back(&threadWork);
printf("THREAD INSTANTIATED\n");
for(auto& thread:threadList){
thread.join();
}

Related

How to handle infinite loop in threads and avoid memory leak

I have a project which run several infinite loops in threads, I simplify it to the following code:
#include <iostream>
#include <vector>
#include <thread>
#include <boost/fiber/algo/round_robin.hpp>
#include <boost/thread.hpp>
#include <chrono>
#include <boost/thread.hpp>
#include <string>
void foo(){
std::cout<<"thread a"<<std::endl;
while(true){
std::this_thread::sleep_for(std::chrono::seconds{5});
}
return;
}
void foo2(){
std::cout<<"thread b"<<std::endl;
while(true){
std::this_thread::sleep_for(std::chrono::seconds{5});
}
return;
}
int main(){
std::thread a(foo);
std::thread b(foo2);
while(true){
std::this_thread::sleep_for(std::chrono::seconds{5});
}
return 0;
}
It works as expected.
I use valgrind to detect memory leak and it shows it has memory leak(I guess infinite loop never release memory because it never stops). I considered to use join(), but it doesn't make sense here. I tried to add
a.detach();
b.detach();
before the while loop in main function, but it doesn't solve memory leak issue.
Would somebody please give me some advice how to avoid memory leak here?
Its a long answer, so I'll start with a summary: The leak in your example code is not an issue. Nevertheless you should fix it. And the way to fix it is to turn the infinite loops into non-infinite loops and to join the threads.
A memory leak is for example this:
void bar() {
int * x = new int;
}
An object is dynamically allocated and when the function returns all pointers to the object are lost. The memory is still allocated to the process but you cannot free it. Calling bar many times will pile up memory until the process runs out of memory and gets killed. This is to be avoided.
Then there is a less severe type of memory leaks:
int main() {
bar();
}
Here some memory is allocated, but next the process terminates. When the process terminates all memory is reclaimed by the OS. The missing delete is not such a big issue here.
There are other ways of leaking memory and I am not trying to enumerate them all, but rather use the examples to get a point across.
Then there are good reasons to worry also about this second type of leaks, that I called "less severe". And that is because it is typically not just memory that is leaked. Consider (dont write code like this! it is only for illustrating a point):
int main() {
A* = new A();
}
A is some class. In main some memory is allocated and an A is constructed. The memory is the lesser problem here. The real problem is any other resource that A claimed in its constructor. It might have opened a file. It might have opened a connection to a data base. Such resources must be cleaned up in a destructor. If the A object is not properly destroyed critical data might get lost.
Conclusion: Leaking memory when returning from main isn't a big issue. Leaking other resource is a big issue. And the memory leak is good indication that also other resources are not cleaned up properly.
In your toy example there is no problem but only a small change makes your approach problematic:
void foo(){
A a;
while(true){
std::this_thread::sleep_for(std::chrono::seconds{5});
}
}
A is again the class that acquires some resource in its constructor and that resouce must be properly release in the destructor. Also when the program terminates you want to have the data in the database, the last log message in the log file, etc.
Rather than while(true) and detach you should use some atomic or condition variable to signal the threads that they should stop. Something along the line of
std::atomic<bool> foo_runs;
void foo(){
A a;
while(foo_runs.load()){
std::this_thread::sleep_for(std::chrono::seconds{5});
}
}
int main() {
foo_runs.store(true);
std::thread a(foo);
// do something else
foo_runs.store(false);
a.join();
}
Whatever you do, you have to join()/detach() on a and b. If you call join() before the main loop, you'll never get to the main loop. If you get to the end of main() without join()/detach(), std::abort() will be called.
I don't see a leak, but there is a race on the cout stream. Maybe potential leak can happen if detached thread a or b escapes main() and continues running a never-ending function. In such case, the thread itself is leaked since it is detached from *this (main), and there is no owner to destroy it. If that's the story, try to call join() on both a and b after the main loop.

Can the thread object be deleted after std::thread::detach?

I have a question about std::thread::detach(). In cplusplus.com it says 'After a call to this function, the thread object becomes non-joinable and can be destroyed safely', by which it seems to mean that the destructor ~thread() may be called safely.
My question is, does this mean that it is ok & safe to delete a thread object immediately after calling detach(), as in the following sample code? Will the function my_function continue safely, and safely use its thread_local variables and variables that are global to the program?
#include <thread>
#include <unistd.h>
void my_function(int t)
{
sleep(t);
}
int main()
{
std::thread *X = new std::thread(my_function, 10);
X->detach();
delete X;
sleep(30);
return 0;
}
The code 'runs' ok, I just want to know if this is safe from the point of view of memory ownership. My motivation here is to have a program that runs 'forever', and spawns a few child threads from time to time (e.g. every 30 seconds.) Each child thread then does something, and dies: I do not want to have to somehow keep track of the children in the parent thread, call join() and then delete.

Reacting threads needing its OWN COPY of the std::shared_future that refers to the share state

I have a question about page 270 of Effective Modern C++, written by the Scott Meyers.
Line 5/6, He writes: "The only subtlety is that each reacting thread needs ITS OWN COPY of the std::shared_future that refers to the shared state, ..."
My question is: Why are we obliged to pass a copy of the std::shared_future to each lambda function in each thread? Whereas à priori, I don't see any problem to pass it by reference, such that there is a unique shared state that would be used by different thread?
I wrote a code adapted from the book of Dr Scott Meyers which works, even if I pass sf par reference.
Thus, is it possible to pass it by reference?
#include <future>
#include <vector>
std::promise<void> p;
void react(){}
void detect()
{
auto sf = p.get_future().share();
std::vector<std::thread> vt;
int n=10;
for(int i=0;i < n; i++)
{
vt.emplace_back([sf]{sf.wait();
react();
});
}
p.set_value();
for(auto& t : vt)
t.join();
}
int main()
{
detect();
return 0;
}
If you pass by reference, multiple threads are accessing the same instance of shared_future. This potentially results in a data race and is undefined behavior. If multiple threads access the shared state via their own copy of shared_future, the library makes sure that they are synchronized.
The cppreference page on get says:
It effectively calls wait() in order to wait for the result.
And the cppreference page on wait says:
Calling wait on the same std::shared_future from multiple threads is
not safe; the intended use is for each thread that waits on the same
shared state to have a copy of a std::shared_future.

Creating std threads in C++ crashes the program

Whenever I execute the following piece of code using threads, the program has this error:
Debug Error!
Program: ... /path/to/.exe
abort() has been called
I want to create a thread that calls a member function. Here is the function I am using:
void ServerVote::createConnexionThreads()
{
for (int i = 0; i <= 50; ++i)
{
m_connexionThreads.push_back(&(std::thread(&ServerVote::acceptConnection,*this, i)));
}
for (int i = 0; i <= 50; ++i)
{
m_connexionThreads[i]->join();
}
}
I can provide additional code if required. When using the debugger, I find that the program crashes right after the first thread is created, after the thread is pushed_back. ~thread() is then called and it crashes inside this function. Here is the vector declaration:
std::vector<std::thread*> m_connexionThreads;
I am using Visual Studio 2015. The acceptConnection function has a while(true) inside it and is planned to be terminated later.
Edit:
Thank you for your answers, but I cannot compile when using a thread object instead of a pointer. So when I try to push into this vector:
std::vector<std::thread> m_connexionThreads;
for (int i = 0; i <= 50; ++i)
{
m_connexionThreads.push_back((std::thread(&ServerVote::acceptConnection,*this, i)));
}
I get this error while compiling:
error C2280: 'std::thread::thread(const std::thread &)': attempting to reference a deleted function
You should not try to use address of the temporary in any context. As a matter of fact, this is a bug in MSVC which allows this code. Any standard-conforming compiler would produce an error here.
Instead, you should use the thread object like this (see my edit below the code on why this is preferred):
#include <thread>
#include <vector>
void acceptConnection(int);
void foo() {
std::vector<std::thread> vec;
for (int i = 0; i <= 50; ++i)
vec.push_back(std::thread(acceptConnection, i));
}
Why this approach is preferred over using an allocated pointer to the thread object? There are multiple benefits:
It is less typing - and even if nothing else, all things being equal (though they are not!) less typing wins over more typing.
It takes caution to use the pointers. For instance, you shouldn't use the raw pointer as vector data type, you should use unique_ptr to ensure automatic memory cleanup - which makes the syntax even uglier!
Using dynamically allocated memory is a drag on performance. You are hit twice - first time when you allocate memory, second time when you free it. Why suffer this penalty?
You are creating a local instance of thread in stack, taking its address and pushing it to the vector. The thread object will be deleted on exit of the method, so you will be left with a pointer to a deleted object.
You should use new to create the thread object in heap so it will not be deleted on method exit, or not use pointers to thread objects.

Reusing thread in loop c++

I need to parallelize some tasks in a C++ program and am completely new to parallel programming. I've made some progress through internet searches so far, but am a bit stuck now. I'd like to reuse some threads in a loop, but clearly don't know how to do what I'm trying for.
I am acquiring data from two ADC cards on the computer (acquired in parallel), then I need to perform some operations on the collected data (processed in parallel) while collecting the next batch of data. Here is some pseudocode to illustrate
//Acquire some data, wait for all the data to be acquired before proceeding
std::thread acq1(AcquireData, boardHandle1, memoryAddress1a);
std::thread acq2(AcquireData, boardHandle2, memoryAddress2a);
acq1.join();
acq2.join();
while(user doesn't interrupt)
{
//Process first batch of data while acquiring new data
std::thread proc1(ProcessData,memoryAddress1a);
std::thread proc2(ProcessData,memoryAddress2a);
acq1(AcquireData, boardHandle1, memoryAddress1b);
acq2(AcquireData, boardHandle2, memoryAddress2b);
acq1.join();
acq2.join();
proc1.join();
proc2.join();
/*Proceed in this manner, alternating which memory address
is written to and being processed until the user interrupts the program.*/
}
That's the main gist of it. The next run of the loop would write to the "a" memory addresses while processing the "b" data and continue to alternate (I can get the code to do that, just took it out to prevent cluttering up the problem).
Anyway, the problem (as I'm sure some people can already tell) is that the second time I try to use acq1 and acq2, the compiler (VS2012) says "IntelliSense: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type". Likewise, if I put std::thread in front of acq1 and acq2 again, it says " error C2374: 'acq1' : redefinition; multiple initialization".
So the question is, can I reassign threads to a new task when they have completed their previous task? I always wait for the previous use of the thread to end before calling it again, but I don't know how to reassign the thread, and since it's in a loop, I can't make a new thread each time (or if I could, that seems wasteful and unnecessary, but I could be mistaken).
Thanks in advance
The easiest way is to use a waitable queue of std::function objects. Like this:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include <chrono>
class ThreadPool
{
public:
ThreadPool (int threads) : shutdown_ (false)
{
// Create the specified number of threads
threads_.reserve (threads);
for (int i = 0; i < threads; ++i)
threads_.emplace_back (std::bind (&ThreadPool::threadEntry, this, i));
}
~ThreadPool ()
{
{
// Unblock any threads and tell them to stop
std::unique_lock <std::mutex> l (lock_);
shutdown_ = true;
condVar_.notify_all();
}
// Wait for all threads to stop
std::cerr << "Joining threads" << std::endl;
for (auto& thread : threads_)
thread.join();
}
void doJob (std::function <void (void)> func)
{
// Place a job on the queu and unblock a thread
std::unique_lock <std::mutex> l (lock_);
jobs_.emplace (std::move (func));
condVar_.notify_one();
}
protected:
void threadEntry (int i)
{
std::function <void (void)> job;
while (1)
{
{
std::unique_lock <std::mutex> l (lock_);
while (! shutdown_ && jobs_.empty())
condVar_.wait (l);
if (jobs_.empty ())
{
// No jobs to do and we are shutting down
std::cerr << "Thread " << i << " terminates" << std::endl;
return;
}
std::cerr << "Thread " << i << " does a job" << std::endl;
job = std::move (jobs_.front ());
jobs_.pop();
}
// Do the job without holding any locks
job ();
}
}
std::mutex lock_;
std::condition_variable condVar_;
bool shutdown_;
std::queue <std::function <void (void)>> jobs_;
std::vector <std::thread> threads_;
};
void silly (int n)
{
// A silly job for demonstration purposes
std::cerr << "Sleeping for " << n << " seconds" << std::endl;
std::this_thread::sleep_for (std::chrono::seconds (n));
}
int main()
{
// Create two threads
ThreadPool p (2);
// Assign them 4 jobs
p.doJob (std::bind (silly, 1));
p.doJob (std::bind (silly, 2));
p.doJob (std::bind (silly, 3));
p.doJob (std::bind (silly, 4));
}
The std::thread class is designed to execute exactly one task (the one you give it in the constructor) and then end. If you want to do more work, you'll need a new thread. As of C++11, that's all we have. Thread pools didn't make it into the standard. (I'm uncertain what C++14 has to say about them.)
Fortunately, you can easily implement the required logic yourself. Here is the large-scale picture:
Start n worker threads that all do the following:
Repeat while there is more work to do:
Grab the next task t (possibly waiting until one becomes ready).
Process t.
Keep inserting new tasks in the processing queue.
Tell the worker threads that there is nothing more to do.
Wait for the worker threads to finish.
The most difficult part here (which is still fairly easy) is properly designing the work queue. Usually, a synchronized linked list (from the STL) will do for this. Synchronized means that any thread that wishes to manipulate the queue must only do so after it has acquired a std::mutex so to avoid race conditions. If a worker thread finds the list empty, it has to wait until there is some work again. You can use a std::condition_variable for this. Each time a new task is inserted into the queue, the inserting thread notifies a thread that waits on the condition variable and will therefore stop blocking and eventually start processing the new task.
The second not-so-trivial part is how to signal to the worker threads that there is no more work to do. Clearly, you can set some global flag but if a worker is blocked waiting at the queue, it won't realize any time soon. One solution could be to notify_all() threads and have them check the flag each time they are notified. Another option is to insert some distinct “toxic” item into the queue. If a worker encounters this item, it quits itself.
Representing a queue of tasks is straight-forward using your self-defined task objects or simply lambdas.
All of the above are C++11 features. If you are stuck with an earlier version, you'll need to resort to third-party libraries that provide multi-threading for your particular platform.
While none of this is rocket science, it is still easy to get wrong the first time. And unfortunately, concurrency-related bugs are among the most difficult to debug. Starting by spending a few hours reading through the relevant sections of a good book or working through a tutorial can quickly pay off.
This
std::thread acq1(...)
is the call of an constructor. constructing a new object called acq1
This
acq1(...)
is the application of the () operator on the existing object aqc1. If there isn't such a operator defined for std::thread the compiler complains.
As far as I know you may not reused std::threads. You construct and start them. Join with them and throw them away,
Well, it depends if you consider moving a reassigning or not. You can move a thread but not make a copy of it.
Below code will create new pair of threads each iteration and move them in place of old threads. I imagine this should work, because new thread objects will be temporaries.
while(user doesn't interrupt)
{
//Process first batch of data while acquiring new data
std::thread proc1(ProcessData,memoryAddress1a);
std::thread proc2(ProcessData,memoryAddress2a);
acq1 = std::thread(AcquireData, boardHandle1, memoryAddress1b);
acq2 = std::thread(AcquireData, boardHandle2, memoryAddress2b);
acq1.join();
acq2.join();
proc1.join();
proc2.join();
/*Proceed in this manner, alternating which memory address
is written to and being processed until the user interrupts the program.*/
}
What's going on is, the object actually does not end it's lifetime at the end of the iteration, because it is declared in the outer scope in regard to the loop. But a new object gets created each time and move takes place. I don't see what can be spared (I might be stupid), so I imagine this it's exactly the same as declaring acqs inside the loop and simply reusing the symbol. All in all ... yea, it's about how you classify a create temporary and move.
Also, this clearly starts a new thread each loop (of course ending the previously assigned thread), it doesn't make a thread wait for new data and magically feed it to the processing pipe. You would need to implement it a differently like. E.g: Worker threads pool and communication over queues.
References: operator=, (ctor).
I think the errors you get are self-explanatory, so I'll skip explaining them.
I think you need a much more simpler answer for running a set of threads more than once, this is the best solution:
do{
std::vector<std::thread> thread_vector;
for (int i=0;i<nworkers;i++)
{
thread_vector.push_back(std::thread(yourFunction,Parameter1,Parameter2, ...));
}
for(std::thread& it: thread_vector)
{
it.join();
}
q++;
} while(q<NTIMES);
You also could make your own Thread class and call its run method like:
class MyThread
{
public:
void run(std::function<void()> func) {
thread_ = std::thread(func);
}
void join() {
if(thread_.joinable())
thread_.join();
}
private:
std::thread thread_;
};
// Application code...
MyThread myThread;
myThread.run(AcquireData);