Reputation: 105
I have a nasty error using pthreads in C/C++. The attached code can be used to reproduce it:
#include <iostream>
#include <vector>
#include <random>
#include <pthread.h>
using namespace std;
const int NUM_THREADS = 2;
//These structs don't serve a specific purpose,
//but are necessary to reproduce the error
struct my_struct {
float a;
float x;
float y;
float z;
};
struct my_param {
struct my_struct my_struct_obj;
vector<struct my_struct>* my_struct_vec;
float t;
};
void* thread_function(void* arg){
struct my_param param = *(struct my_param*)(arg);
printf("Param values for (x, y, z): (%f, %f, %f)\n",
param.my_struct_obj.x, param.my_struct_obj.y, param.my_struct_obj.z);
return NULL;
}
void run_multithread_function(vector<struct my_struct> &my_struct_vec,
struct my_struct obj, float a){
void* exit_status[NUM_THREADS];
pthread_t thread_IDs[NUM_THREADS];
//holds the parameter for the functions assigned
vector<struct my_param> thread_params;
//create the threads
for(unsigned int i = 0; i < NUM_THREADS; i++){
struct my_param parameter;
parameter.my_struct_obj = obj;
parameter.my_struct_vec = NULL;
thread_params.push_back(parameter);
pthread_create(&thread_IDs[i], NULL, thread_function, &thread_params[i]);
}
//join the threads
for(unsigned int i = 0; i < NUM_THREADS; i++){
pthread_join(thread_IDs[i], &exit_status[i]);
}
}
int main() {
vector<struct my_struct> mass_objects;
struct my_struct my_obj;
my_obj.x = 1;
my_obj.y = 1;
my_obj.z = 1;
float a = 8;
run_multithread_function(mass_objects, my_obj, a);
}
The problem is that the variable passed to the thread seems to be somelike overwritten, as the snippets outputs
Param values for (x, y, z): (0.000000, 1.000000, 1.000000) Param values for (x, y, z): (1.000000, 1.000000, 1.000000)
instead of all 1.000000. All the snippet does is creating two new threads, and passing each of them the function
void* thread_function(void* arg)
with the argument
&thread_params[i]
which is the address of an item in a vector of structs. I was unable to find the source of the mentioned error and would appreciate any hints. What I have found out, it that reordering the variables in my struct to
struct my_param {
vector<struct my_struct>* my_struct_vec;
struct my_struct my_struct_obj;
float t;
};
somehow seems to solve the problem. Furthermore, if the function
thread_function
is called directly (without creating a thread), the error disappears as well. Therefore, I assume that I make some pthread-related mistake. Any suggestions?
Upvotes: 0
Views: 180
Reputation: 14890
There are no guarantees with respect to the initial allocation size of thread_params
, so as you push into the vector and simultaneously pass thread_params[i]
to the threads you cannot really say that reallocation won't occur on the second push_back
.
Push the values into the vector in a separate loop, or set an initial capacity:
vector<struct my_param> thread_params;
thread_params.reserve(2);
Upvotes: 3