Passing instance of a class to pthread_create - c++

My question is somehow related to this post:
pthread_create error:
I am trying to call a multiple instances of a solver (which is a class perhaps) on different cores. For this I wrote a chuck of code and used pthread_creat() function. Following is my effort:
void *MultiThread(void *threadid)
{
long tid;
tid = (long)threadid;
if(tid==0)
{
cout<< "load thread number "<< tid;
DefaultSolver s1(sys1,prec);
s1.time_limit=time_limit;
s1.trace= true;
sols1=s1.solve(pair2.first);
cout << "number of solutions from solver 1=" << sols1.size() << endl;
cout << "cpu time used=" << s1.time << "s."<< endl;
cout << "number of cells=" << s1.nb_cells << endl;
pthread_exit(NULL);
}
if(tid==1)
{
cout<< "load thread number "<< tid;
DefaultSolver s2(sys2,prec);
s2.time_limit=time_limit;
s2.trace=true;
sols2=s2.solve(pair2.second);
cout << "number of solutions from solver 2=" << sols2.size() << endl;
cout << "cpu time used=" << s2.time << "s."<< endl;
cout << "number of cells=" << s2.nb_cells << endl;
pthread_exit(NULL);
}}
Now DefaultSolver is a class from which I am instantiating 2 instances and declaration should be done on different cores, and then I am using different functions of that class through the declared instances s1 and s2. Following is the code where I am calling this function. Following is the remaining piece of code:
double convert(const char* argname, const char* arg) {
char* endptr;
double val = strtod(arg,&endptr);
if (endptr!=arg+strlen(arg)*sizeof(char)) {
stringstream s;
s << "\"" << argname << "\" must be a real number";
ibex_error(s.str().c_str());
}
return val;
}
int main(int argc, char** argv)
{
pthread_t threads[NUM_THREADS];
int rc;
int i;
try{
// check the number of arguments
if (argc<4) {
ibex_error("usage: defaultsolver filename prec timelimit");
}
vector<IntervalVector> sols1, sols2, sols3, sols4;
System sys1(argv[1]);
System sys2(sys1, System::COPY);
System sys3(sys1, System::COPY);
System sys4(sys1, System::COPY);
double prec = convert("prec", argv[2]);
double time_limit = convert("timelimit",argv[3]);
double bisect = convert("bisect",argv[4]);
pair<IntervalVector,IntervalVector> pair1=sys1.box.bisect(bisect);
pair<IntervalVector,IntervalVector> pair2 = pair1.first.bisect(bisect);
pair<IntervalVector,IntervalVector> pair3= pair1.second.bisect(bisect);
for( i=0; i < NUM_THREADS; i++ ){
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL,
MultiThread, (void *)i);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);}
And following is the error when I am trying to make it:
parallel2.cpp: In function ‘void* MultiThread(void*)’:
parallel2.cpp:29:26: error: ‘sys1’ was not declared in this scope
parallel2.cpp:29:31: error: ‘prec’ was not declared in this scope
parallel2.cpp:30:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:32:3: error: ‘sols1’ was not declared in this scope
parallel2.cpp:32:18: error: ‘pair2’ was not declared in this scope
parallel2.cpp:50:20: error: ‘sys2’ was not declared in this scope
parallel2.cpp:50:25: error: ‘prec’ was not declared in this scope
parallel2.cpp:51:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:53:3: error: ‘sols2’ was not declared in this scope
parallel2.cpp:53:18: error: ‘pair2’ was not declared in this scope
parallel2.cpp:64:20: error: ‘sys3’ was not declared in this scope
parallel2.cpp:64:25: error: ‘prec’ was not declared in this scope
parallel2.cpp:65:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:67:3: error: ‘sols3’ was not declared in this scope
parallel2.cpp:67:18: error: ‘pair3’ was not declared in this scope
parallel2.cpp:80:20: error: ‘sys4’ was not declared in this scope
parallel2.cpp:80:25: error: ‘prec’ was not declared in this scope
parallel2.cpp:81:17: error: ‘time_limit’ was not declared in this scope
parallel2.cpp:83:3: error: ‘sols4’ was not declared in this scope
parallel2.cpp:83:18: error: ‘pair3’ was not declared in this scope
Is there any way to fix it? or is there any other easy way in c++11?

The variables (sys1, sys2, ... sols1, sols2... prec etc.) are local variables inside your main function, so they are not accessible in your function MultiThread. [Edit: Usually you can only pass one parameter to a thread. If you want to pass multiple parameters you have to create a "container" holding them - a class or a record.]
The ugly solution is to make global variables out of them.
The more common approach is to create a class or record holding all data you need inside your thread, create one instance for each thread and pass that object as the parameter. So you probably even don't neet to know your thread id.
Quick hack:
Create a container class:
class MyThreadParams
{
public:
// you can add getters/setters and hide the member variables if you want
long threadId; //still needed?
System *pSys;
double prec;
double time_limit;
// further values /objects you need
};
In your thread function, cast the parameter to that class and use its values instead of your variables you tried to access from here.
void *MultiThread(void *threadParams)
{
MyThreadParams* pParams = reinterpret_cast<MyThreadParams*>(threadParams);
cout<< "load thread number "<< tid;
DefaultSolver solver(pParams->sys1, pParams->prec);
solver.time_limit = pParams->time_limit;
//and so on
}
The decision which objects shall be used for whicht thread has been done in main when filling MyThreadParams, so you if (threadId == 1) can be ommitted, think.
int main(int argc, char** argv)
{
....
MyThreadParams threadParams[NUM_THREADS];
....
// fill params for 1st thread
threadParams[0].threadId = 0;
threadParams[0].pSys = &sys1;
threadParams[0].prec = convert("prec", argv[2]);
threadParams[0].time_limit := convert("timelimit",argv[3]);
// further values /objects you need
// fill params for 2nd thread
threadParams[1].threadId = 1;
threadParams[2].pSys = &sys2;
threadParams[3].prec = convert("prec", argv[2]);
// and so on
rc = pthread_create(&threads[i], NULL,
MultiThread, reinterpret_cast<void *>(&threadParams[i]));
}
You have to decide whether you want the thread params to be the owner of the System object and the sols etc. or should only carry references/pointer to them and let the exist inside main.

Related

Can't properly transfer data from a class in C++

I am trying to make a simple game
What will happen is a player will be hit by various objects that result in increase/ decrease of health
The mainGame(); is created just to see if its working properly.
On compilation i get this
(.text$_ZN5gamer7setDataEv[__ZN5gamer7setDataEv]+0x117)||undefined reference to `gamer::mainGame()'|
I tried the friend keyword but that gave me the error of undefined reference to object
class gamer
{
public:
string gName;
int gHealth;
int continueGame;
void mainGame();
void setData()
{
cout << "Enter your name " <<endl;
cin >> gName;
srand(time(0));
gHealth = 100 + (rand()%200);
cout << gName << " has health of " << gHealth << endl;
cout << "Would you like to continue ? 0 for yes" << endl;
cin >> continueGame;
if (continueGame == 0)
{
mainGame();
}
}
};
void mainGame()
{
gamer gamer;
while(gamer.gHealth >= 0 || gamer.gHealth <= 500)
{
cout << " aaaaaa" << endl;
gamer.gHealth -= 50;
cout << gamer.gHealth << endl ;
}
}
You have declared the mainGame function as a member of your gamer class but never actually defined it. You came close, but forgot to declare, in the definition, that it a member of the class. The below should work:
void gamer::mainGame() // This is a member function of `gamer`, so declare it as such!
{
// gamer gamer; // We don't need this reference, as the member function will have...
while(gHealth >= 0 || gHealth <= 500) // ... an implied "this" object when called
{
cout << " aaaaaa" << endl;
gHealth -= 50; // Just using the member name on its own is enough to get it.
cout << gHealth << endl ;
}
}
Inside a member function, you don't need code declaring an object of that class! When the function is called (by an object of the class) the function effectively receives a pointer to the object that called it; you can explicitly access this pointer with the this keyword but, generally, you don't need to. Just using the name of a member variable in that function will reference that member variable for the object that called the function.

Seg-fault when trying to swapcontext() into a struct member that is stored in a queue

I've defined a struct called thread with a member called ucontext* tctx.
In a function called create_thread(), I create a thread object on the heap and define each one of its members (including the members of the ucontext object). I then add the pointer to that thread object into a queue-container.
When I pop the queue to swap into a thread's context, I seg-fault. I'm not sure why this happens.
Here is the full code:
#include <iostream>
#include <queue>
#include <ucontext.h>
#define STACK_SIZE 262144
using namespace std;
typedef struct thread
{
int thread_id;
ucontext* tctx;
char* sp;
}thread;
int thread_id;
ucontext_t* ctx1; //Unused, currently
ucontext_t* cur;
queue<thread*> ready_queue;
/* Function Declaration */
thread* create_thread(int,int);
void foo1(int);
int main(int argc, char** argv)
{
cout << " PROGRAM START ***** \n";
/* Create 'i' number of threads */
for(int i = 0; i < 2; i++)
{
cout << "\nready_queue size before creating thread = " << ready_queue.size() << endl;
cout << "Calling create thread ... id=" << i << endl;
create_thread(i, i*1000);
cout << "ready_queue size after creating thread = " << ready_queue.size() << endl;
}
cout << " \t>> THREADS CREATED \n";
cout << " \t>> SWITCHING CONTEXT \n";
/* Save current context to cur, swap context to first thread in queue */
swapcontext(cur, ready_queue.front()->tctx); //Seg fault!
cout << " PROGRAM TERMI ***** \n";
return 0;
}
thread* create_thread(int id, int arg)
{
static int num_threads = 0;
/* Create a new thread struct, ucontxt for the thread, and put in ready queue */
thread* n = new thread;
getcontext(n->tctx);
n -> thread_id = id;
n -> tctx = new ucontext_t;
n -> sp = new char[STACK_SIZE];
n->tctx->uc_stack.ss_sp = n->sp;
n->tctx->uc_stack.ss_size = STACK_SIZE;
n->tctx->uc_stack.ss_flags = 0;
n->tctx->uc_link = NULL;
makecontext(n->tctx, (void(*)()) foo1, 1, arg); //Thread shall call foo() with argument 'arg'
/* Push new thread into ready_queue */
ready_queue.push(n);
num_threads++;
cout << "Thread #" << num_threads << " was created. Thread.ID[" << id << "]\n";
return n;
}
//Application function
void foo1(int arg)
{
cout << "Calling from foo1(). I have " << arg << "!\n";
}
Edited:
I noticed that if I call getcontext(n->tctx); after n -> tctx = new ucontext_t; the problem is resolved. It seems to be that the problem might be that getcontext was trying to initialize something in the heap that had not yet been allocated.
The ucontext_t* cur pointer is dangling, that is why it swapcontext crashes. You could allocate a valid value (new ucontext_t), but it's better to make its type ucontext_t rather than a pointer. The same also counts for thread.tctx and there is no need to keep thread.sp a pointer either.
However, C++11 has std::thread which is a much better alternative to what you are trying to do and this would be the proper C++ approach. Also if you want to learn something new, I'd recommend to focus on std::thread instead. There's a nice tutorial here: https://solarianprogrammer.com/2011/12/16/cpp-11-thread-tutorial/
By the way, in your example getcontext(n->tctx); is also called on an uninitialized tctx and you have a lot of unfreed memory at the end of your program...

c++ how to access variable from member function?

I have a problem. I want to operate with single element of an array, which is generated in member function, but it doesn´t work. Here is my code:
using namespace std;
class Example
{
public:
int *pole;
void generate_pole();
};
void Example::generate_pole()
{
int *pole = new int [10];
for (int i = 0; i < 10; i++)
{
pole[i] = i;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Example reference;
reference.generate_pole();
cout << reference.pole[1] << endl; //there is the problem
system("pause");
return 0;
}
How can I get an access to the element? And where is the real problem? Thank you!
int *pole = new int [10]; is creating an identically named variable pole in local scope. This is shadowing the member variable.
A fix, drop the int* from the errant line: pole = new int [10];
That said, I'd be inclined to use a constructor to set the member variable in this case: certainly you should initialise pole to nullptr by default. This is so you can delete[] pole in a destructor when an instance of your class goes out of scope. Else your code will leak memory like a colander leaks water.
An other way would be to use std::vector<int> pole; and let the C++ standard library take care of all the memory for you.
The problem is, that you shadow pole's name in the scope of the function by redeclaring it. leave the int * in front of pole behind, in generate_pole, and it should work.
An example for shadowing:
int i = 0; // i is 0
std::cout << "before scope: " << i << std::endl; // prints 0
{
int i = 1;
std::cout << "inside scope: " << i << std::endl; // prints 1
}
std::cout << "behind scope: " << i << std::endl; // prints 0

Calling strings as functions in C++

I'm writing a 'skeleton' front-end in native C++ for other users where the users are creating functions that I will 'call' depending on arguments that are passed in. For example:
skeleton.exe /foo param1
would be used to call the function "int doFoo(param1){return 0;}" inside my skeleton. As more team members write functions, I would need to add those functions as well.
A stray thought I had - and I'm not even certain if this would be possible - would be to have a resource file - or, maybe, a resource xml file - that would list the command line arguments, the number of parameters and then the function I need to call for that parameter. So my resource file for the above would look like:
foo 1 doFoo
This way, as people create their functions, all they have to do is add it to the resource file.
The problem I am running into - and what I'm wondering if it is even possible - is whether I can 'interpret' that 'doFoo' as a function if it is read from the resource file. Is there anything that would allow me to 'interpret' a string as a function I can call?
You will need to map strings to function pointers.
One method is to create a lookup table another is to use std::map.
Search the internet for "c++ dispatch" and maybe "c++ double dispatch".
I think I've got it! I just need to ensure that each added function is declared with extern "C" __declspec(dllexport)! Example:
extern "C" __declspec(dllexport) int square(int x)
{
return (x*x);
}
typedef int(__cdecl *MYPROC)(int);
int _tmain(int argc, _TCHAR* argv[])
{
LPCSTR funcName = "square";
HMODULE hMod = GetModuleHandle(NULL);
if (hMod != NULL)
{
cout << "hMod is not NULL!" << endl;
MYPROC abstractSquare = (MYPROC)GetProcAddress(hMod, funcName);
if (NULL != abstractSquare)
{
cout << "abstractSquare is not NULL!" << endl;
int y = (abstractSquare)(10);
cout << "y = " << y << "!" << endl;
}
else
{
cout << "abstractSquare is NULL!" << endl;
}
}
else
{
cout << "hMod is NULL!" << endl;
}
return 0;
}

Thread hangs in pthread_rwlock_t

I have this simple thread creation progrm in c++, during when a RW lock is declared globally, progrmm executes as expected, but when the same lock declaration is made local (i.e., Inside the function) only one thread executes, the other thread hangs.
WORKING:
#include <iostream>
#include <pthread.h>
using namespace std;
int i = 0;
**pthread_rwlock_t mylock;** //GLOBAL
void* IncrementCounter(void *dummy)
{
cout << "Thread ID " << pthread_self() << endl;
int cnt = 1;
while (cnt < 50)
{
pthread_rwlock_wrlock(&mylock);
++i;
pthread_rwlock_unlock(&mylock);
++cnt;
cout << "Thread ID ( " << pthread_self() << " ) Incremented Value : " << i << endl;
}
}
int main()
{
pthread_t thread1,thread2;
int ret, ret1;
ret = pthread_create(&thread1,NULL,IncrementCounter,NULL);
ret1 = pthread_create(&thread2,NULL,IncrementCounter,NULL);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
}
*NON WORKING:*
#include <iostream>
#include <pthread.h>
using namespace std;
int i = 0;
void* IncrementCounter(void *dummy)
{
cout << "Thread ID " << pthread_self() << endl;
int cnt = 1;
**pthread_rwlock_t mylock;** //LOCAL
while (cnt < 50)
{
pthread_rwlock_wrlock(&mylock);
++i;
pthread_rwlock_unlock(&mylock);
++cnt;
cout << "Thread ID ( " << pthread_self() << " ) Incremented Value : " << i << endl;
}
}
int main()
{
pthread_t thread1,thread2;
int ret, ret1;
ret = pthread_create(&thread1,NULL,IncrementCounter,NULL);
ret1 = pthread_create(&thread2,NULL,IncrementCounter,NULL);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
}
What could be the possible reason for this?
In neither case are you correctly initialising the mylock variable - you are just getting "lucky" in the first case. The correct initialisation in the global case would be:
pthread_rwlock_t mylock = PTHREAD_RWLOCK_INITIALIZER;
In the local case, if you want your threads to be accessing the same lock, then it has to be declared static:
static pthread_rwlock_t mylock = PTHREAD_RWLOCK_INITIALIZER;
That's what you want in this case, because you're protecting access to the global i. The lock should be associated with the data, so if i is global then really it makes sense for mylock to be global also.
If you really wanted non-static locks (which in this case, you don't), you would use:
pthread_rwlock_t mylock;
pthread_rwlock_init(&mylock, NULL);
followed by:
pthread_rwlock_destroy(&mylock);
at the end of the function.
In addition to what the other answers say, consider that in C and C++ all variables with static storage (e.g. mylock in your first example) are initialized to zero.
Simplifying, pthread_rwlock_t is a struct.
In your first example, mylock has static storage duration, so all of its internal members were initialized to zero. By chance, this equivalent to the "unlocked" state of pthread_rwlock_t, as the macro PTHREAD_RWLOCK_INITIALIZER mentioned in another answer initializes exactly everything to zero; in nptl/sysdeps/pthread/pthread.h you can find:
#define PTHREAD_RWLOCK_INITIALIZER \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
Therefore all runs of your first example will always exhibit the same behavior (i.e. the lock will start unlocked).
In your second example, mylock is not initialized, because it has automatic storage duration. The behavior will then be dependent on what other values happen to be lying the that uninitialized area of memory. Most of the times, the lock with start in "locked" state, but, if you're lucky (on unlucky) enough, it will instead start unlocked.
The reason is quite clear, you even say so yourself... In the working version the variable is global, while in the non-working the variable is local.
A local variable is only known inside the function, during that call. So if a function is called twice then the variable is unique on both these calls.
If you want to use a local variable, you can mark it static, as that makes it "static" between all invocations of the function.
I suggest you read more about variable scoping and lifetime.