This question already has answers here:
Start thread with member function
(5 answers)
Closed 4 years ago.
Suppose there's
class concurr{
public:
double arr[100];
void func1(vector<vector<double>> data,int x);
double func2(vector<vector<double>> data);
}
such that func2 takes in "data" and feeds it to func1 with the same "data" but varying numbers of x as it goes from 0 to up to 100. Then in func1, it calculates something and whatever the double value it comes out, fills it up for arr[x] So basically, the func2 looks generally like
double concurr::func2(vector<vector<double>> data){
thread threads[100];
for (int x = 0; x < 100; x++){
threads[x] = thread(concurr::func1,data,x); // this line is where the problem is
}
for (auto& th : threads){
th.join();
}
// ..... does something with the arr[100].... to come up with double = value
return value;
}
and without the multithreading part, the code runs well, it's just that with the added multithreading part, when I try to compile, it says
"reference to non-static member function must be
called"
When calling member function with a thread you need to pass an object of the class or a ref to it (in your case itself):
threads[x] = thread(concurr::func1, *this,data,x);
Or use a lambda
threads[x] = thread( [&]{ this->func1(data, x); } )
Related
This question already has answers here:
Pass by reference and value in C++
(5 answers)
Closed 5 years ago.
I wrote the folloing code to test how to change values of class object in a function.
using namespace std;
class test{
public:
int a;
};
void runer(test testXX){
testXX.a=10;
}
int main()
{
test test1;
test1.a=5;
runer(test1);
cout<<test1.a;
return 0;
}
When I run the following code the output is 5 and not 10. Is it because I can't change the values of class instances, like I can't change the values of array members without using pointers? I would be grateful if someone could clarify that!
void runer(test testXX){
testXX.a=10;
}
Takes a full copy of the type test, so it is modified in the function, but a different instance to the one in main.
Parameters in C++ are sent by value. The simplest example which makes sense is
int function( int value ) {
for( ; value > 0 ; value-- ){
cout << "Hello\n";
}
}
int main( int , char ** ){
int value = 10;
function( value ); // display 10 things
function( value ); // display 10 things again (not modified).
function( 5 ); // also not making sense, if parameter is modified.
}
To allow objects to be modified, they need to be sent as references, or pointers. This allows the value of the item to be changed. The literal 5 can not be sent to a function expecting a reference.
void runer(test & testXX){
testXX.a=10;
}
Now the same object is sent from main to runner, and modifications are done to the single object.
You are passing the argument to the function by value, so it gets a local copy that only lives as long as the scope of the function.
If you want the function to be able to modify the original object that you pass in, then pass it by non-const reference void runer(test& testXX) .
Your code makes a call by value. Hence, the change doesn't appear in the actual object. To change the value of the attribute of the object you need to make a call by reference.
void runer(test &t){
t.a = 10;
}
This question already has answers here:
Is local static variable initialization thread-safe in C++11? [duplicate]
(2 answers)
Closed 6 years ago.
Suppose I have a class with three static functions like this :
#include <vector>
#include <iostream>
using namespace std;
#include <thread>
class Employee
{
};
class client
{
public:
void Doprocessing()
{
//is this thread safe in c++11/14
static int i = CreateEmployee();
//does it look good to use static variable like this to make it thread safe?
static int k = ProcessEmploye();
}
private:
static int CreateEmployee()
{
static Employee * e = new Employee();
InsertEmployee(e);
return 1;
}
static int InsertEmployee(Employee *e)
{
vec.push_back(e);
return 1;
}
static int ProcessEmploye()
{
Employee* e = vec[0];
//do something with e
//...
//.
//Suppose 10 -20 lines
return 1;
}
static std::vector<Employee*> vec;
};
std::vector<Employee*> client::vec;
void func()
{
client cobj;
cobj.Doprocessing();
}
const int No_Of_Threads = 10;
int main() {
std::thread * threadpointer = new std::thread[No_Of_Threads];
std::srand(11);
for (int i = 0; i < No_Of_Threads; i++)
{
threadpointer[i] = std::thread(func);
}
for (int i = 0; i < No_Of_Threads; i++)
{
threadpointer[i].join();
}
delete[] threadpointer;
std::cout << " Good" << std::endl;
return 0;
}
My questions are :
1)If I use static int i = Somefunc() and no matter how bulky somefunc is, will be called once and will it be thread safe ?
2) if answer of 1) is yes, Does it look good to programers eyes to use static int i = SomeFunc() for above purpose.
Yes, it will be thread safe, but only since C++11. Static variables are initialized in thread safe way, they are often also called magic statics.
For more see here: http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables
If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once (similar behavior can be obtained for arbitrary functions with std::call_once).
Note: usual implementations of this feature use variants of the double-checked locking pattern, which reduces runtime overhead for already-initialized local statics to a single non-atomic boolean comparison.
Also - in your code you call CreateEmployee(); during initialization of static i, and CreateEmployee( also initializes a static variable. This should also be OK, you can find in standard following footnote:
The implementation must not introduce any deadlock around execution of the
initializer.
As to your second question, from the code you have shown I dont see that it is OK to use static variable as a way to gain thread safety.
Are you aware that specifying a variable as static inside function body allows you to assign it only once? This means your CreateEmployee() will always return the same Employee instance.
I create the two following objects:
bool Reception::createNProcess()
{
for (int y = 0; y < 3; ++y)
{
Process *pro = new Process; // forks() at construction
Thread *t = new Thread[5];
this->addProcess(pro); // Adds the new process to a vector
if (pro->getPid() == 0)
{
for (int i = 0; i < 5; ++i)
{
pro->addThread(&t[i]); // Adds the new thread to a vector
t[i].startThread();
}
}
}
Where I create 3 processes (that I have encapsulated in Process) and create 5 threads in each of these processes.
But I'm not sure the following line is correct:
Thread *t = new Thread[5];
Because my two functions addProcess and addThread both take a pointer to Process and Thread respectively and yet the compiler asks for a reference to t[i] for addThread and I don't understand why.
void Process::addThread(Thread *t)
{
this->threads_.push_back(t);
}
void Reception::addProcess(Process *p)
{
this->createdPro.push_back(p);
}
createdPro is defined in the Reception class as follows:
std::vector<Process *> createdPro;
and threads_ in the Process class like such:
std::vector<Thread *> threads_;
And the error message (as obvious as it is) is as follows:
error: no matching function for call to ‘Process::addThread(Thread&)’
pro->addThread(t[i]);
process.hpp:29:10: note: candidate: void Process::addThread(Thread*)
void addThread(Thread *);
process.hpp:29:10: note: no known conversion for argument 1 from ‘Thread’ to ‘Thread*’
Even though I defined my Thread as a pointer.
You have defined the member function to take a pointer:
void Process::addThread(Thread *t)
{
...
}
You then invoke this function for &t[i], which is a pointer and should work perfectly:
pro->addThread(&t[i]); // Adds the new thread to a vector
You could also invoke it with t+i and it would still be ok. However your error message tells us something different: the compiler doesn't find a match for pro->addThread(t[i]); (i.e. the & is missing).
Either you made a typo in your question, or you made a typo in your code. Or you have another invocation somewhere where you've forgotten the ampersand: t[i] would of course designate an object (it's equivalent to *(t+i) ) and not a pointer, and cause the error message you have (demo mcve)
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
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ member-function pointer
How to invoke pointer to member function when it's a class data member?
I've only recently started using C++, so I apologize if the following contains any trivial mistakes, or if I missed an easier solution. I would like to achieve something like this:
class ClassA {
typedef double (ClassA::*CondFunc)();
public:
ClassA(int x, int y) {
value_ = x;
switch (y) {
case 0:
condFunc_ = &ClassA::condA;
break;
case 1:
condFunc_ = &ClassA::condB;
default:
break;
}
}
~ClassA();
int value_;
CondFunc condFunc_;
double condA() { return 2.0*value_; }
double condB() { return 4.0*value_; }
void Test() {
int a = condFunc_(); // compile error
}
};
but get a compile error in Test(). Please note that this is a vastly simplified function and is not supposed to make any sense. I've searched this forum and elsewhere for answers, but am still not sure whether defining/calling such non-static member function pointers is even possible. The only plausible hint/solution I've come across employs a static wrapper function to achieve something similar. I'd be grateful for any help/clarifications.
You have to call the member pointer function like this:
int a = (this->*condFunc_)();