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.
Related
I'm calling a class function in parallel using OpenMP. It's working okay in serial or putting the my_func part in the critical section (slow apparently). Running in parallel, however, keeps giving the following error message,
malloc: *** error for object 0x7f961dcef750: pointer being freed was
not allocated
I think the problem is with the new operators in the my_func, i.e., The pointer myDyna seems to be shared among threads. My questions are,
1)Isn't anything inside the parallel region private, including all the pointers in the my_func? Meaning that, each thread should have its own copy of myDyna, but why the error occurred?
2)Without changing the my_func too much, what can be done to make the parallelization work at the main level? For example, would it work by adding a copy constructor in the myDyna?
void my_func(){
Variables *theVars = new Variables();
//trDynaPS Constructor for the class.
trDynaPS *myDyna = new trDynaPS(theVars, starttime, stepsize, stoptime);
ResultRate = myDyna->trDynaPS_Drive(1, 1);
if (theVars != nullptr) {
myDyna->theVars = nullptr;
delete theVars;
}
delete myDyna;
};
int main()
{
#pragma omp parallel for
{
for (int i = 0;i<10;i++){
//I have multiple copies of myclass as a vector
myclass[i]->run(); //my_func is in the run operation
}
}
return 0;
}
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();
}
For example, I have:
int main()
{
int i = 0;
std::thread t([&] {
for (int c = 0; c < 100; ++c)
++i;
});
t.join();
return 0;
}
The thread t change the variable i value.
I think, that when OS changes current thread it must save an old thread stack and copy a new thread stack.
How does operation system provide a right access to the i?
Does it exists any explanation, how it works on an operating system level?
Does it more productive if I will use something like:
int main()
{
int* i = new int;
std::thread t([&] {
for (int c = 0; c < 100; ++c)
++(*i);
});
t.join();
return 0;
}
There are two separate things at play in your example code: capture of local variables to a lambda function and how threads and their stacks work.
Capture of local variables when a lambda function is created works the same way regardless of whether the lambda is in the same thread or a different thread. Basically references to the variables are passed to the lambda.
See How are C++11 lambdas represented and passed? for more details.
Threads, as commented by Margaret Bloom, share the address space of a process. They gave access to read and modify the same memory (including e.g. global variables). While each thread has a different stack area allocated to it, the stacks are all in the address space of the process so all threads can access the stack area of the other threads. So if a thread has a pointer or a reference to a variable in another threads stack, it can read and modify that.
Adding these 2 things together makes your example code work.
The first version of your code is probably slightly more efficient because there is one less level of indirection.
Here is my code:
vector<MyClass> objs;
objs.resize(4);
vector<thread> multi_threads;
multi_threads.resize(4);
for(int i = 0; i < 4; i++)
{
multi_threads[i] = std::thread(&MyFunction, &objs[i]);
// each thread change some member variable in objs[i]
multi_threads[i].join();
}
I expect that the elements in objs can be changed at each thread. Then after the threads finished, I can get access to the member data.
However, when the program finished the above loop, the member variables I'd like to get is not changed at all.
I guess this is because the multi-threading mechanism in C++, but I don't know what exactly I did wrong. And may I know how to achieve my expectation?
Many thanks.
=================================================================================
EDIT:
Here is the source code of MyFunc:
void MyFunc(MyClass &obj)
{
vector<thread> myf_threads;
myf_threads.resize(10);
for(int i = 0; i < 10; i++)
{
myf_threads[i] = std::thread(&AnotherClass::increaseData, &obj);
myf_threads[i].join();
}
}
And here is AnotherClass::increaseData:
void AnotherClass::increaseData(Myclass& obj)
{
obj.add();
}
void MyClass::add()
{
data++;
}
objs is empty when first accessed, causing undefined behaviour:
multi_threads[i] = std::thread(&MyFunction, &objs[i]);
//^^ 'objs' is empty, so this access
// is out-of-bounds.
There must be instances of MyClass within objs before accessing it. Avoid potential reallocation of the internal buffer used by the objs vector by allocating the required number of elements upfront. If reallocation occurs previous pointers acquired would be dangling:
std::vector<MyClass> objs(4);
std::vector<std::thread> multi_threads(objs.size());
To avoid sequential execution of the threads join() with the threads in a subsequent loop instead of in the creation loop:
for(int i = 0; i < 4; i++)
{
multi_threads[i] = std::thread(&MyFunction, &objs[i]);
}
for (auto& t: multi_threads) t.join();
See demo.
After the update, it appears the function being used for the thread is taking a reference, not a pointer, to a MyClass instance (even though a pointer is being passed to the std::thread constructor?). In this case, std::ref(objs[i]) must be used to avoid copying of the MyClass instance by the std::thread constructor (see demo). Note from the std::thread::thread() reference page:
The arguments to the thread function are copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).
Maybe
std::ref(objs[i])
helps you.
I had the same problem with referenced parameters in the function for the thread
and that helped me.
This question is a refinement of this one, which went in a different direction than expected.
In my multithreaded application, the main thread creates parameters and stores them:
typedef struct {
int parameter1;
double parameter2;
float* parameter3;
} jobParams;
typedef struct {
int ID;
void* params;
} jobData;
std::vector<jobData> jobs;
// main thread
for (int i = 0; i < nbJobs; ++i) {
jobParams* p = new jobParams;
// fill and store params
jobData data;
data.ID = i;
data.params = p;
jobs.push_back(data);
}
// start threads and wait for their execution
// delete parameters
for (int i = 0; i < jobs.size(); ++i) {
delete jobs[i].params;
}
Then, each thread gets a pointer to a set of parameters, and calls a job function with it:
// thread (generic for any job function and any type of params)
jobData* job = main->getNextParams();
jobFunction(job->ID, job->params);
The whole thing takes void* as argument to be able to use any structure for the parameters, but then the job function casts it back to the right struct:
void* jobFunction(void* param) {
jobParams* params = (jobParams*) param;
// do stuff
return 0;
}
My problem is the following: if I delete params at the end of jobFunction(), it works perfectly. However, I'd prefer to have the deletion taken care of by the threads or the main thread, such that I don't have to remember to delete the params for each jobFunction() that I write.
If I try to delete params just after calling jobFunction() in the treads, or even in the main thread after being sure that all threads are done (and thus the params are not needed anymore), I get a heap corruption error:
HEAP[prog]: Invalid Address specified to RtlFreeHeap( 02E90000, 03C2EE38 )
I'm using Visual Studio 2008 Pro, and I thus can't use valgrind or other *nix tools for debugging. All access to the main thread from the "child threads" are synchronized using a mutex, so the problem is not that I delete the same parameters twice.
In fact, by using VS memory viewer, I know that the memory pointed by the jobParams pointer does not change between the end of jobFunction() and the point where I try to delete it (either in the main thread or in the "child threads").
I added the definition of both structures, as well as the way I'd like to delete the params.
Just as a thought .. can you try
for (int i = 0; i < jobs.size(); ++i) {
delete (jobParams*)jobs[i].params;
}
newing a type jobParams and then deleteing a void* might be the cause of your problems.
Is there any reason you store params as a void* in jobData? I'd argue if you wish to have different types of jobParams then you should be using an inheritance hierarchy and not blindly casting to a void*.
That sort of bug generally means you have a data race somewhere. Does main->getNextParams() do the right thing even if it's called by several threads at once? If it gives the same params to both, you could have a double-free in your hands.
Also, instead of
jobFunction(jobData->ID, jobData->params);
You probably meant
jobFunction(job->ID, job->params);
To debug it you could add a deleted member to the jobParams class and set that to true instead of actually deleting the object. Then see check the deleted flag in every method of jobParams and throw an exception if it's true. Then see where the exception gets thrown.