Trouble referencing class in structure using this keyword - c++

Header file:
// Free function to use in thread
unsigned int __stdcall WorkerFunction(void *);
class MyClass {
public:
int temp;
void StartThread();
}
typedef struct {
MyClass * cls;
} DATA;
CPP class:
void MyClass::StartThread() {
temp = 1234;
DATA data = {this};
HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, &data, 0, 0);
// Commented out for now while I address the current problem
//CloseHandle(hThread);
}
unsigned int __stdcall WorkerFunction(void * param0) {
MessageBox(NULL, "WorkerFunction()", "Alert", MB_OK);
DATA * data = (DATA *) param0;
MyClass* cls0 = data->cls;
// Crashes when reference to cls0 is attempted.
char buf[5];
snprintf(buf, 5, "%i", cls0 ->temp);
MessageBox(NULL, buf, "Alert", MB_OK);
}
I've got an easy problem here that I can't put my finger on.
I have params for a thread, which pass a struct which contains a class.
I instantiate the struct with this and then pass it when the thread starts
I try to dereference (?) it in the worker function.
At this point, everything compiles OK.
When I add lines to access something in the class, the app crashes.
Where is my mistake?

You're passing a local stack variable that is out-of-scope the moment StartThread() returns. You are therefore referencing stack-space that no longer belongs to you.
void MyClass::StartThread() {
temp = 1234;
DATA data = {this}; // << LOCAL VARIABLE OUT OF SCOPE ON FUNCTION EXIT
HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, &data, 0, 0);
// Commented out for now while I address the current problem
//CloseHandle(hThread);
}
Either dynamically allocate the data, or better still, make the data a member of MyClass and pass this as the thread data. In your case you're only passing *this anyway through a struct, so just pass it as the param
void MyClass::StartThread() {
temp = 1234;
HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, this, 0, 0);
// Commented out for now while I address the current problem
//CloseHandle(hThread);
}
And in your thread proc:
unsigned int __stdcall WorkerFunction(void * param0) {
MessageBox(NULL, "WorkerFunction()", "Alert", MB_OK);
MyClass* cls0 = static_cast<MyClass*>(param0);
etc...
}
Whatever you pass to your thread procedure, it must have valid lifetime for the duration required. by the thread. Either ensure that by passing ownership of a dynamic allocation to the thread at let it do the delete, or pass a pointer known hold determinate state for the lifetime of its usage in the thread-proc. It appears this fulfills the latter, so you should likely be good to go.

Related

How to pass in the 'this' pointer to a C++ WinAPI thread?

I am trying to run a C++ thread but also pass in the instance to the class itself. I cannot seem to figure it out.
I have a struct for parameters to the thread:
struct CLASS_PARAMS {
SomeClass* ptr;
};
I then call my setup method:
void SomeClass::setup() {
CLASS_PARAMS params;
params.ptr = this;
CreateThread(NULL, 0, SetupThread, &params, 0, NULL);
}
and right above SomeClass::setup(), I define SetupThread:
DWORD WINAPI SetupThread(LPVOID lpParam) {
CLASS_PARAMS* params = (CLASS_PARAMS *) lpParam;
SomeClass* inst = params->ptr;
....
....
}
However, I get read-access violations on using inst. I have other methods in SomeClass that I need to access via the thread:
inst->getSomeValue();
...
inst->setSomeValue(someValue);
...
but it will not allow me. Any suggestions on what I'm doing wrong?
You allocate CLASS_PARAMS on stack, so it is destroyed before used.
Allocate it dynamically, pass pointer and free it in the thread.
Alternatively, if you need to pass only this, pass it without wrapping structure, just cast to LPVOID and back (but be sure to use the same class pointer type to avoid pointer adjustment bugs)

why should we bind a key to a memory block by pthread_setspecific rather than just keep the pointer to that block?

As usual, we use pthread_setspecific to bind a dynamically allocated block to a global key.
void do_something()
{
//get thread specific data
int* glob_spec_var = pthread_getspecific(glob_var_key);
*glob_spec_var += 1;
}
void* thread_func(void *arg)
{
int *p = malloc(sizeof(int));
*p = 1;
pthread_setspecific(glob_var_key, p);
do_something();
pthread_setspecific(glob_var_key, NULL);
free(p);
pthread_exit(NULL);
}
However, if I simplify thread_func to this:
void do_something(int* p)
{
//get thread specific data
int* glob_spec_var = p; //pthread_getspecific(glob_var_key);
*glob_spec_var += 1;
}
void* thread_func(void *arg)
{
int *p = malloc(sizeof(int));
*p = 1;
// pthread_setspecific(glob_var_key, p);
do_something(p);
// pthread_setspecific(glob_var_key, NULL);
free(p);
pthread_exit(NULL);
}
It will do exactly the same thing with the last version. the pointer p is also different in each thread. So why do we have to bind the memory to a key, rather than just keep the pointer?
You can indeed implement your own thread-specific storage by allocating it within the thread start function, then passing a pointer to it to every thread function, and freeing it on thread exit.
The advantage of the pthread_setspecific() / pthread_getspecific() interface is that it lets you avoid that bookkeeping - in particular, the need to pass that pointer to your thread-specific storage down through all of your code paths in case some leaf function needs it is quite onerous.
It also means that library code can access thread-local storage without requiring the library user to set it up and pass it in to the library on every call.

passing one function to different threads

I have to create an application where I'll have to make multiple threads. SoI thought to try making one function and passing it to different threads. Initially I've created two threads and have declared one function to be passed to both of them. All I am trying to do is to pass different integers to those threads and display it in the thread function,here is my code:
DWORD WINAPI Name(LPVOID lpParam)
{
int *Ptr=(int*)lpParam;
for(int j=0;j<2;j++)
{
cout<<"Thread"<<endl;
cout<<*Ptr<<endl;
}
return 0;
}
int main()
{
int a=10,b=15,c=25;
HANDLE thread1,thread2;
DWORD threadID,threadID2;
thread2= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
thread1= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);
for(int i=0;i<5;i++)
{
cout<<"Main Thread"<<endl;
}
if(thread1==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
if(thread2==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
return 0;
}
but this code is not running properly,i.e compliles fine,starts fine but afterwards gives a debugging error.
Could someone let let me know of my mistake and how I could correct it coz being able to utilize one function for multiple threads will be really helpful for me.
Wait for your child threads to return. Do this:
int main()
{
int a=10,b=15,c=25;
HANDLE thread[2];
DWORD threadID,threadID2;
thread[1]= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
thread[0]= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);
for(int i=0;i<5;i++)
{
cout<<"Main Thread"<<endl;
}
if(thread[0]==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
if(thread[1]==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
CloseHandle(thread[0]);
exit(0);
}
WaitForMultipleObjects(2, thread, TRUE, INFINITE);
CloseHandle(thread[0]);
CloseHandle(thread[1]);
return 0;
}
The handle of a thread is signaled when the thread is terminated (refer CreateThread).
You are passing the address of a local variable in the function into your thread. By the time the thread gets around to running your function has probably exited main already. So the thread will try to access a variable that no longer exists on the stack so will be reading some random value which when you try to dereference it as a pointer will likely crash.
You main needs to wait. For a simple test just put in a Sleep(10000) or something before it exits. Obviously that's no use for a real program.
To summarize the comments: There are two ways you can pass data. Either directly inside the void pointer, because "void pointer" is an integral type and thus can represent integers (but it doesn't necessarily have the same width as int), or indirectly by passing an actual address of the thing you care about.
Method 1 (pass the value):
DWORD WINAPI Name(LPVOID lpParam)
{
intptr_t n = reinterpret_cast<intptr_t>(lpParam);
// ...
}
int main()
{
intptr_t a = 10;
thread1 = CreateThread(NULL, 0, Name, reinterpret_cast<void *>(a), 0, &threadID);
// ... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
For this method, we use the integral type intptr_t, which has the same width as void *. We use reinterpret-casts to store and retrieve arbitrary integral values.
Method 2 (pass a pointer):
DWORD WINAPI Name(LPVOID lpParam)
{
T * p = static_cast<T *>(lpParam);
// ... use *p ...
}
int main()
{
T thing_I_care_about;
thread1 = CreateThread(NULL, 0, Name, &thing_I_care_about, 0, &threadID);
// ... ^^^^^^^^^^^^^^^^^^^
}
This is the more general method, but requires that thing_I_care_about remain alive, and it becomes a brittle shared state, so lifetime management and synchronisation become issues. Note that any object pointer is implicitly convertible to void *, so there's no need for the cast at the call site.
Finally, as others have commented, don't forget to join or detach your threads.

Defining function inside function call

I had an idea to save time involving creating a temporary function to use as an argument to a function that needs it. The reason I'm after this behaviour is to do things in a new thread in an easy manner (using Win32 API) without having to define all kinds of functions I'll use.
Here's an example:
void msg (const string & message) {
MessageBox (0, message.c_str(), "Message", 0);
}
This will produce a message box, but your program is halted until it closes. The solution is to create a thread for the message box that runs concurrently with the main thread.
void msg (const string & message) {
CreateThread (0, 0,
(LPTHREAD_START_ROUTINE)({MessageBox (0, message.c_str(), "Message", 0);}),
0, 0, 0);
}
In this case, LPTHREAD_START_ROUTINE is defined as
typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID param);
Since I have multiple functions wanting another thread for a purpose like that, putting the function in the call to CreateThread seems to be working well.
But say I wanted to use that LPVOID param. I'd like to know how standard this method is, and where I can find out how to use it for more advanced techniques. Also, I know using it in a function that will store it for later use (eg. a message loop function where you can add messages to handle and a corresponding function to call) is a bad idea as the function is temporary and would not be able to be called when needed. Is there really any use beyond things like threads where it's annoying to make one line functions elsewhere in order to use it?
It's called a "lambda". They are very useful for many purposes beyond this and are in the C++11 Standard. You can find them in the latest GCC and MSVC. However, MSVC's current implementation does not permit conversion to a function pointer, as the Standard did not specify such a conversion at that time. VC11 will implement this conversion. This code is Standard-conforming C++11:
void msg (const string & message) {
CreateThread (0, 0,
[](LPVOID* param) { MessageBox (0, message.c_str(), "Message", 0); },
0, 0, 0);
}
There was another way in times lambdas were not the standard - you could define function-local class and define the inner function within that class. Something like:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(LPVOID param)
{
/// do the action
return 0;
}
};
::CreateThread(0, 0,
&message_box::display,
0, 0, 0);
}
Now lets consider your question. You wanted to pass the message text in STL's std::string. Since it occupies dynamic memory which can be freed by your initial thread, the new thread, running in parallel, must have guarantee, that the message text will still be available to it. This can be done by copying (which would work with lambda's by-value capture - [=] introducer) or sharing a reference (via reference counting, let'd say). Lets consider copying:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(void *param)
{
MessageBox(0, ((string *)param)->c_str(), "Message", 0);
delete (string *)param;
return 0;
}
};
string *clone = new string(message);
::CreateThread(0, 0,
&message_box::display,
clone, 0, 0);
}
Please, note, that the copy is allocated in the initial thread and destroyed in the new one. This requires multithreading support from your CRT.
In the case new thread fails to start, you'll end up with memory being orphaned. Lets fix this:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(void *param)
{
auto_ptr<string> message((string *)param);
MessageBox(0, message->c_str(), "Message", 0);
return 0;
}
};
auto_ptr<string> clone(new string(message));
if (::CreateThread(0, 0, &message_box::display, clone.get(), 0, 0))
clone.release(); // release only if the new thread starts successfully.
}
Since the memory is being managed by the CRT, the CRT have to be initialized in the new thread, which is not done by CreateThread API. You have to use CRT beginthread/beginthreadex instead:
void msg(const string &message)
{
struct message_box
{
static unsigned int WINAPI display(void *param)
{
auto_ptr<string> message((string *)param);
MessageBox(0, message->c_str(), "Message", 0);
return 0;
}
};
auto_ptr<string> clone(new string(message));
if (_beginthreadex(0, 0, &message_box::display, clone.get(), 0, 0))
clone.release(); // release only if the new thread starts successfully.
}
This solution leaves aside the problem of the thread itself being leaked as a resource. But, I believe you may find another posts for this on stackoverflow.com :)
thanks )

How to get pointer from another thread?

Let's have the following class definition:
CThread::CThread ()
{
this->hThread = NULL;
this->hThreadId = 0;
this->hMainThread = ::GetCurrentThread ();
this->hMainThreadId = ::GetCurrentThreadId ();
this->Timeout = 2000; //milliseconds
}
CThread::~CThread ()
{
//waiting for the thread to terminate
if (this->hThread) {
if (::WaitForSingleObject (this->hThread, this->Timeout) == WAIT_TIMEOUT)
::TerminateThread (this->hThread, 1);
::CloseHandle (this->hThread);
}
}
//*********************************************************
//working method
//*********************************************************
unsigned long CThread::Process (void* parameter)
{
//a mechanism for terminating thread should be implemented
//not allowing the method to be run from the main thread
if (::GetCurrentThreadId () == this->hMainThreadId)
return 0;
else {
m_pMyPointer = new MyClass(...);
// my class successfully works here in another thread
return 0;
}
}
//*********************************************************
//creates the thread
//*********************************************************
bool CThread::CreateThread ()
{
if (!this->IsCreated ()) {
param* this_param = new param;
this_param->pThread = this;
this->hThread = ::CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))this->runProcess, (void *)(this_param), 0, &this->hThreadId);
return this->hThread ? true : false;
}
return false;
}
//*********************************************************
//creates the thread
//*********************************************************
int CThread::runProcess (void* Param)
{
CThread* thread;
thread = (CThread*)((param*)Param)->pThread;
delete ((param*)Param);
return thread->Process (0);
}
MyClass* CThread::getMyPointer() {
return m_pMyPointer;
}
In the main program, we have the following:
void main(void) {
CThread thread;
thread.CreateThread();
MyClass* myPointer = thread.getMyPointer();
myPointer->someMethod(); // CRASH, BOOM, BANG!!!!
}
At the moment the myPointer is used ( in the main thread ) it crashes. I don't know how to get the pointer, which points to memory, allocated in another thread. Is this actually possible?
The memory space for your application is accessible to all threads. By default any variable is visible to any thread regardless of context (the only exception would be variables declared __delcspec(thread) )
You are getting a crash due to a race condition. The thread you just created hasn't started running yet at the point where you call getMyPointer. You need to add some kind of synchronization between the newly created thread and the originating thread. In other words, the originating thread has to wait until the new thread signals it that it has created the object.
I'm trying to get my head around what you are trying to do. It looks overly complicated for something like a thread-class. Would you mind post the class-definition as well?
Start by removing the C-style cast of the process-argument to CreateThread():
this->hThread = ::CreateThread (NULL, 0,&runProcess, (void *)(this_param), 0, &this->hThreadId);
If this doesn't compile you're doing something wrong! Never ever cast a function pointer! If the compiler complains you need to change your function, not try to cast away the errors! Really! You'll only make it worse for yourself! If you do it again they* will come to your home and do ... Let's see how you like that! Seriously, don't do it again.
Btw, in Process() I think it would be more appropriate to do something like:
assert(::GetCurrentThreadId() == hThreadId);
But if you declare it private it should only be accessible by your CThread-class anyway and therefor it shouldn't be a problem. Asserts are good though!
*It's not clear who they are but it's clear whatever they do it won't be pleasant!
As Rob Walker pointed out - I really missed the race condition. Also the crash is not when getting the pointer, but when using it.
A simple wait did the job:
MyClass* myPointer = thread.getMyPointer();
while (myPointer == 0)
{
::Sleep(1000);
}
myPointer->someMethod(); // Working :)