Reputation: 33
I'm trying to pass a function with a parameter form a class into a thread in the main.cpp
This is the error I'm getting:
"Error 1 error C2064: term does not evaluate to a function taking 1 arguments c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional 1149 1 The Dining Philosophers Problem"
I just can't seem to get it working. This is what i have so far:
Philosophers Philosopher;
thread Philosopher_Thread[NUMBEROFPHILOSOPHERS];
int main()
{
for (int Philosopher_Num = 0; Philosopher_Num < NUMBEROFPHILOSOPHERS; Philosopher_Num++)
{
if (Philosopher.Iterations[Philosopher_Num] > 0)
{
Philosopher_Thread[Philosopher_Num] = thread (std::bind(&Philosophers::Hierarchy_Function, &Philosopher_Num)); // Create threads for each philosopher
Philosopher_Thread[Philosopher_Num].join(); //join threads
}
}
}
class.h
class Philosophers
{
public:
void Initialise();
void Hierarchy_Function(int Current_Philosopher);
}
class.cpp
void Philosophers::Hungry_Hierarchy(int Current_Philosopher)
{
//code//
}
Upvotes: 1
Views: 340
Reputation: 161
Because you're binding to a non static member function you need to provide the instance pointer to bind as the first variable arg.
Philosophers Philosopher;
thread Philosopher_Thread[NUMBEROFPHILOSOPHERS];
int main()
{
for (int Philosopher_Num = 0; Philosopher_Num < NUMBEROFPHILOSOPHERS; Philosopher_Num++)
{
if (Philosopher.Iterations[Philosopher_Num] > 0)
{
auto func = std::bind(&Philosophers::Hierarchy_Function, &Philosopher, &Philosopher_Num)
Philosopher_Thread[Philosopher_Num] = thread (func);
Philosopher_Thread[Philosopher_Num].join();
}
}
}
Also I noticed you passed a pointer to Philosopher_Num as the function param, if you're intending to pass the iteration index then this isn't necessary.
Upvotes: 1
Reputation: 28932
The thread creation line should read:
Philosopher_Thread[Philosopher_Num] = thread (std::bind(&Philosophers::Hierarchy_Function, &Philosopher, &Philosopher_Num));
The reason is that Philosophers::Hierarchy_Function
is a class member function. When you call this funcion using Philosopher.Hierarchy_Function(Philsopher_Num);
the compiler supplies an implicit this
pointer as the first argument. So when you call it using a pointer to member function, the this
pointer must be supplied explicitly as a pointer to your object.
Also a note of caution, you are sharing the same Philosopher amongst all your threads, this has the potential to result in a race condition (you have no internal state so you are ok in the above example) so either have a separate Philosopher for each thread or provide some form of synchronization.
Upvotes: 1
Reputation: 409442
You don't need std::bind
when using std::thread
. Just do e.g.
std::thread(&Philosophers::Hierarchy_Function, Philosopher, Philosopher_Num);
The above also fixes two other problems: The first that since Hierarchy_Function
is not a static
member function, it must be called on a specific object instance of the Philosophers
class (the second argument to the thread
constructor). The second problem is that you attempted to pass a pointer to an integer to the function as argument, but the function wants an integer value.
Also, creating a thread, and then immediately joining that thread is no different than just calling the function and doing the calculations serially. Have two loops, one creating the threads, and then when you're done tell the threads to exit (by having e.g. a single boolean variable that the thread checks) and then have a loop joining the threads.
Upvotes: 2