boost::thread - Simple example doesn't work (C++) - c++

To get started with boost::thread, I've written a very simple example -- which doesn't work. Could anyone point out my mistake?
I wrote a very simple functor-type class to do the work. It's supposed to compute the sum of an std::vector of doubles, and give me a way to get the result later:
class SumWorker
{
private:
double _sum;
public:
SumWorker() : _sum(-1.0) {}
void operator() (std::vector<double> const & arr)
{
_sum = 0.0;
for(std::vector<double>::const_iterator i = arr.begin();
i != arr.end();
i++)
{
_sum += (*i);
}
}
double const value() const
{
return _sum;
}
};
Now, I can compute the sum in one of two ways. If I do it within the main thread, like,
SumWorker S;
S(numbers); // "numbers" is an std::vector<double>
double sum = S.value(); // "sum" now contains the sum
then everything works. However, if I try to do this in a separate thread (which was the whole point),
SumWorker S;
boost::thread thread(S, numbers); // Should be equivalent to "S(numbers);"
thread.join(); // Wait for thread to finish
double sum = S.value(); // "sum" now contains -1.0
...then it doesn't work.
Sorry if this is obvious, but I'm stumped. Any clues?

You should use
boost::thread thread(boost::ref(S), boost::cref(numbers));
since by default thread copies these arguments.

Your SumWorker object S is being copied by the thread constructor therefore its member is never updated.
http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.thread.callable_constructor

Related

forward_list iterators incompatible

I'm trying to complete a program that evaluates polynomials when given an x-value.
The polynomials are stored using the STL's forward_list in objects of the class.
class PolyTerm {
private:
int _order = 0;
double _coeff = 0.0;
public:
PolyTerm() = default;
PolyTerm(int order, double coefficient) : _order(order), _coeff(coefficient) {}
void setOrder(int order) { _order = order; }
void setCoeff(double coeff) { _coeff = coeff; }
int getOrder() const { return _order; }
double getCoeff() const { return _coeff; }
};
My function which takes the object and the x-value is written as follows:
double evaluate(const forward_list<PolyTerm>& terms, double x) {
double answer = 0;
forward_list<PolyTerm>::iterator it;
while (it != terms.end()) {
answer += it->getCoeff() * pow(x, it->getOrder());
it++;
}
return answer;
}
My compiler doesn't show any errors but once I try to run the program, I get a pop-up saying "Debug Assertion Failed!" with Expression: forward_list iterators incompatible
Image of pop-up
I'm pretty sure I declared the iterator to be of the same type as the list holding the polynomial so I'm not sure why I'm getting this error.
Can anyone explain to me what's wrong?
Thanks in advance for any help.
forward_list<PolyTerm>::iterator it; it's not initialized. It must be initialized with the first element of the forward list.
forward_list<PolyTerm>::iterator it = terms.begin();
You may simplify you loop, and you will not use it
for (const auto& term : terms)
answer += term.getCoeff() * pow(x, term.getOrder());
You also could have used std::accumulate, as that will enforce the initialization using the third argument to the function. Also, since there is no need to declare and initialize iterators, there is no chance you will forget to initialize the iterator.
Here is an example. Note that there are no hand-written loops:
#include <numeric>
//...
double evaluate(const forward_list<PolyTerm>& terms, double x)
{
return std::accumulate(terms.begin(), terms.end(), 0.0, // <-- Note the initial value is 0.0 -- you can't miss it
[&](double total, const PolyTerm& p)
{ return total + p.getCoeff() * pow(x, p.getOrder()); });
}
You never initialize it.
You should have used a for loop.
You should have used a C++11 for(auto it: terms) as I think it would go.

C++ threads and variables

I have a problem within the program that I write. I have functions returning pointers and within the main() I want to run them in threads.
I'm able to execute the functions in threads:
double* SplitFirstArray_1st(double *arr0){
const UI arrSize = baseElements/4;
std::cout << "\n1st split: \n";
double *arrSplited1=nullptr;
arrSplited1 = new double [arrSize];
for(UI i=0; i<arrSize; i++){
arrSplited1 = arr0;
}
for(UI j=0; j< arrSize; ++j){
std::cout << arrSplited1[j] << " ";
}
return arrSplited1;
delete [] arrSplited1, arr0;
}
in main()
std::thread _th1(SplitFirstArray_1st, rootArr);
_th1.join();
The above is not what I'm after. I have another pointer:
*arrTh1=nullptr;
I would like to use it in a thread so it would be assigned with the value returned by my function SplitFirstArray_1st
arrTh1 = SplitFirstArray_1st(xxx);
Is such action is possible to be executed in a tread ?
Don't return the variable, pass a pointer to the variable and set the value at what this points too.
i.e.:
void set_int(int* toset) {
*toset = 4;
}
This works fine with things that are already pointers:
void set_ptr(int** toset) {
*toset = new int[4];
// ...
*toset[0] = 2;
}
You can know the data is safe to use if the function has returned.
Completely unrelated note:
return foo;
// No point placing code here unless you used goto as it won't get executed.
// Also: don't use goto.
}
Something like this:
std::thread _th1([&]() { arrTh1 = SplitFirstArray_1st(rootArr); });
Functions which start the thread cannot return values in a normal way. Therefore they should be declared as void.
Common way is to assign a protected global variable. You should protect one with mutexes (or other methods) to avoid races.
mutex m;
double *arrTh1 = nullptr;
double* aSplitFirstArray_1st(double *arr0){
...
m.lock();
arrTh1 = arrSplited1;
m.unlock();
}
When you use the pointer in other threads (including the main one), you need to protect the usage as well with the same mutex (or choose other methods).
and please, do not delete arrSopited1 and arr0. it will make the arrTh1 pointer unusable.
Note, if you use async functions, you could use futures to return values.

Using function object in stl algorithm

When trying to use a conditional copy_if algorithm to copy only the values that are lower than mean of values in a vector into another vector, I hit a snag with my function object:
struct Lower_than_mean
{
private:
double mean;
vector<double>d1;
public:
Lower_than_mean(vector<double>a)
:d1{a}
{
double sum = accumulate(d1.begin(), d1.end(), 0.0);
mean = sum / (d1.size());
}
bool operator()(double& x)
{
return x < mean;
}
};
int main()
{
vector<double>vd{ 3.4,5.6, 7, 3,4,5.6,9,2 };
vector<double>vd2(vd.size());
copy_if(vd.begin(), vd.end(), vd2, Lower_than_mean(vd));
}
What is the right way of going about this?
You used vd instead of vd.begin() in the call to std::copy_if.
But, seriously, you didn't bother to even read your compiler output...
Also, like #zch suggests - your approach doesn't make sense: Don't keep re-calculating the mean again and again. Instead, calculate it once, and then your function becomes as simple [mean](double x) { return x < mean; } lambda.

Is c++11 "range-based for" thread-safe?

I have an environment modelled by lines and points packed in two std::vector.
I want to calculate a field generated by this environnement. I multithreaded the process. As the environment is totally defined at the begining, threads should only read on it so I don't use any syncrhonisation as discribed here and there.
The problem comes now : when I iterate through the lines in the environement, I have two different behaviours depending if I use the c++11 range-based for statment or if I use a more common for statement with iterators.
It seems that the range-based for isn't thread-safe and I'm wondering why?
If I'm not right assuming that, it might significate I have a more deep problem that may reappear latter.
Here is a piece of code, the first worker seems to work, the second provoke a segfault.
Worker::worker(Environement const* e, int id):threadId(id),env(e)
{
}
// worker that seems to do his job.
void Worker::run() const
{
cout<<"in thread n "<<_threadId<<endl;
vector<Line> const* lines = &env->_lines;
for(std::vector<Line>::const_iterator it = lines->begin() ;it != lines->end(); ++it ){
it->hello();
}
}
// create a segfault
void Worker::run2() const
{
cout<<"in thread n "<<_threadId<<endl;
vector<Line> const& lines = env->_lines;
for(auto it : lines){
it.hello();
}
}
The simplified structure of data if needed:
struct Line
{
void hello() const {std::cout<<"hello"<<std::endl;}
}
struct Environment
{
std::vector<Line> _lines;
std::vector<Point> _points;
}

How to convert for loop to STL for_each statement

I would like to convert my for loop to STL std::for_each loop.
bool CMyclass::SomeMember()
{
int ii;
for(int i=0;i<iR20;i++)
{
ii=indexR[i];
ishell=static_cast<int>(R[ii]/xStep);
theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
}
Actually I was planning to use parallel STL from g++4.4
g++ -D_GLIBCXX_PARALLEL -fopenmp
which is allow to run code in parallel without changes if the code is written in standard STL library.
You need to seperate out the loop body into a seperate function or functor; I've assumed all the undeclared variables are member variables.
void CMyclass::LoopFunc(int ii) {
ishell=static_cast<int>(R[ii]/xStep);
theta=atan2(data->pPOS[ii*3+1],
data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
bool CMyclass::SomeMember() {
std::for_each(&indexR[0],&indexR[iR20],std::tr1::bind(&CMyclass::LoopFunc,std::tr1::ref(*this));
}
class F {
public:
void operator()(int ii) {
ishell=static_cast<int>(R[ii]/xStep);
theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
F(int[] r): //and other parameters should also be passed into the constructor
r_(r) {}
void:
int[] r_; // refers to R[ii] array
// and other parameters should also be stored
};
F f(R); // pass other parameters too
for_each(&indexR[0], &indexR[iR20], f);
However it might not be a good idea to use this "automatic parallelization" since you need to keep in mind the grainsize of each parallel computation -- I am not sure how well the compiler takes the grain size into account.
You cannot just separate cycle body into functor and assume that it will be paralellised because you have too many dependencies inside cycle body.
Cycle will be able to run in parallel only if you have no global arrays or pointers. If you provide full function body then we can think how to change it to parallel version.
You'll need to convert the loop body into a function or functor. There are a lot of undeclared variables in there, so I can't easily tell how to separate out the loop body. Here's a stab at it:
class DoStuff
{
int* R;
int xStep;
Data* data;
double massp;
double fm;
double* al2;
public:
DoStuff(int* R_, int xStep_, Data* data_, double massp_, double fm_, double* al2_) :
R(R_), xStep(xStep_), data(data_), massp(massp_), fm(fm_), al2(al2_) {}
void operator()(int ii)
{
int ishell = static_cast<int>(R[ii]/xStep);
double theta = atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
};
for_each(indexR, indexR+iR20, DoStuff(R, xStep, data, massp, fm, al2));