I am creating a new thread in which I am passing passing an object of class
class demo is defined in .h file
int threadentry(void* data)
{
demo* inst=(demo*) data;
cout << "Value of inst "<<hex << &inst<< endl;//value is different from below
}
int main()
{
while(1)
{
demo* inst=new demo();
cout << "Value of inst "<<hex << &inst<< endl; //value is coming different from above
HANDLE threads;
DWORD threadId1;
if ((threads = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadentry,
(void *)inst, 0, &threadId1)) == NULL)
return -1;
delete inst;
system("pause");
}
}
I think value should be different because address is copied in data variable of threadentry. How can I check that these are the same object passed.
The code is printing the address of a pointer, not the address of the object. There are two pointer variables involved (one is declared in main() and the other is the argument of the thread function) so the output is different. Drop the &, address of operator, from the output statements:
cout << "Value of inst "<<hex << inst << endl;
Give ownership of the supplied object to the thread as it knows when it has finished using it. In the posted code the object is deleted after the thread is created, possibly resulting in the thread using a dangling pointer. Move the delete of object from main into the thread.
The signature of the thread function is:
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
);
and it must return a value, the posted code does not.
The code also has a resource leak as the handle returned from CreateThread() is not being closed. Either CloseHandle() immediately if the thread does not need to be joined with or store the thread handles, in a std::vector for example, to be joined with (using WaitForSingleObject for example) and closed later.
You might get a race condition. You delete your class instance right after CreateThread. At this point threadentry() might not start executing yet.
Related
typedef inside header file:
typedef struct tagMYSTRUCT {
wchar_t mystr[40] = { 0 };
DWORD threadId = NULL;
HANDLE threadHandle = NULL;
HWND receiverWnd = NULL;
} MYSTRUCT, *PMYSTRUCT;
Thread creation:
MYSTRUCT ats = *(PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT));
wcscpy(ats.mystr, L"hello");
ats.threadHandle = CreateThread(NULL, 0, MyThread, &ats, 0, &(ats.threadId));
This is thread which uses HeapFree() function. But it crashes. I believe this is bad practice but I want to know why. What is the logic behind and why HeapFree crashes program?
DWORD WINAPI MyThread(LPVOID lpParam) {
MYSTRUCT ActiveStruct = *(PMYSTRUCT)lpParam;
if (lpParam != NULL) {
std::cout << "1" << std::endl; // Gets printed.
HeapFree(GetProcessHeap(), NULL, lpParam);
std::cout << "2" << std::endl; // Crashes before this line.
}
...
}
You've obviously come from another language that blends the concepts of pointers and references differently than C++. Your usage is wildly inappropriate in C++. You have complicated things further by using non-standard functions (HeapAlloc() which is windows specific, not C++, etc) to manage memory.
If you are going to use HeapAlloc() (which is non-standard C++, being windows specific) or any standard function that dynamically allocates memory, the result needs to be stored in a pointer.
MYSTRUCT ats = *(PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT));
wcscpy(ats.mystr, L"hello");
ats.threadHandle = CreateThread(NULL, 0, MyThread, &ats, 0, &(ats.threadId));
What this does is convert the pointer returned by HeapAlloc() into a pointer to MYSTRUCT, dereferences that pointer which interprets that memory location as the value of a MYSTRUCT, and copies that value into ats.
At the least this is a memory leak - the memory allocated by HeapAlloc() is lost (never used again, it's address not stored anywhere), and you are passing the address of ats to the thread function.
There is therefore NO RELATIONSHIP between the memory allocated by HeapAlloc() and the address passed to the thread function.
Even worse is the thread function itself, which I've simplified here
DWORD WINAPI MyThread(LPVOID lpParam)
{
MYSTRUCT ActiveStruct = *(PMYSTRUCT)lpParam;
if (lpParam != NULL)
{
std::cout << "1" << std::endl; // Gets printed.
HeapFree(GetProcessHeap(), NULL, lpParam);
std::cout << "2" << std::endl; // Crashes before this line.
}
}
lpParam is going to contain the address of ats from the function that was passed by the function creating the thread.
If the function creating the thread has returned (after all, threads run in parallel) then that ats will no longer exist. If that happens, lpParam will be a dangling pointer (the address of an object that no longer exists as far as your program is concerned).
ActiveStruct is now going to be a local object which contains a copy of the object at the address passed to the function. In other words, it is a local copy of ats allocated previously by the func. If that ats has ceased to exist, and the address passed is dangling, the simple act of creating ActiveStruct causes undefined behaviour.
Even worse, lpParam is the address of (what was) ats. If ats still exists (i.e. the function which created the thread hasn't returned), it was not created on the heap, so should not be released using HeapFree(). If it no longer exists, then it shouldn't be passed to HeapFree() either. Either way, HeapFree() is being asked to release memory that was not allocated using HeapAlloc(). That will be virtually guaranteed to cause a runtime error.
At minimum, you need to change the code which creates the thread to
MYSTRUCT *ats = (PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT)); // note changed position of *
wcscpy(ats->mystr, L"hello"); // note usage of ats as a pointer
DWORD threadID; // we need these since ats is being released by the thread function
HANDLE threadHandle; // it is not a good idea for CreateThread() to use them
threadHandle = CreateThread(NULL, 0, MyThread, ats, 0, &(threadId)); // changes since ats is now a pointer
and the thread function to
DWORD WINAPI MyThread(LPVOID lpParam)
{
MYSTRUCT *ActiveStruct = (PMYSTRUCT)lpParam; // this is now a pointer
if (lpParam != NULL)
{
std::cout << "1" << std::endl; // Gets printed.
HeapFree(GetProcessHeap(), NULL, lpParam);
std::cout << "2" << std::endl; // Crashes before this line.
}
}
Since you are making fundamentally wrong assumptions about the C++ memory model, I would assume other things (which you haven't shown) are wrong in your code. But this should get you started.
You are getting in something of a mess over this. You are passing the address of a stack allocated structure which you do not intend to do. I think it's clear that you intend to pass the address a heap allocated structure. When you try to deallocate that structure, calling HeapFree, you encounter a runtime error because you passed to HeapFree the address of memory not allocated by HeapAlloc.
I'll show you how it is done using new and delete rather than HeapAlloc and HeapFree. There's really no need to use HeapAlloc here. Use the standard C++ memory allocator.
MYSTRUCT *pats = new MYSTRUCT(); // zero initialise
wcscpy(pats->mystr, L"hello");
DWORD threadId;
HANDLE threadHandle = CreateThread(NULL, 0, MyThread, pats, 0, &threadId);
....
DWORD WINAPI MyThread(LPVOID lpParam)
{
MYSTRUCT ActiveStruct = *(PMYSTRUCT)lpParam;
delete (PMYSTRUCT)lpParam;
// if you want the thread ID, call GetCurrentThreadId
// or if you want a thread handle call GetCurrentThread
}
Note that I did not attempt to store the thread handle and thread ID directly into the structure. That's because the structure could in theory be destroyed before the call to CreateThread returns. I'm using local variables instead. If your thread needs to find its ID, or obtain a handle to itself, there are API calls to do that.
1) you are not checking pointers before casting and dereferencing them
2) you are actually allocating MYSTRUCT on the stack and copy zeros from a heap-allocated buffer of MYSTRUCT size
3) your heap-allocated pointer leaks after copy assignment
4) you are passing pointer to stack-allocated MYSTRUCT instance to CreateThread which becomes invalid right after MYSTRUCT goes out of scope (which may happen at any time before new thread starts, while it works, or after it exits)
5) CreateThread and c++ runtime don't play well together
this is the corrected version if you insist on using HeapAlloc
PMYSTRUCT ats = (PMYSTRUCT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYSTRUCT));
if(ats == NULL)
return; // exit, throw do something
wcscpy(ats->mystr, L"hello");
CreateThread(NULL, 0, MyThread, ats, 0, &(ats.threadId));
HeapAlloc returns a pointer to the allocated memory, that is placed in a pointer. The pointer is then used to manipulate the allocated struct, finally this pointer is passed to the thread. And dont assign the result of createthread to something this is destroyed by the thread.
I am working on a Multithreaded system here's my code
class demo is defined in .h file
when the loop from the main function is executed second time the COMMENT1 below takes the previous value
doesn't closing handle closes the thread?
int threadentry(void* data)
{
demo* inst=(demo*) data;
cout << "Value of inst "<<hex << &inst<< endl;
string request;
cin>>request;
if(request==play)
{
inst->play;
cout << "Value of inst "<<hex << &inst<< endl;
// COMMENT1 here when the thread is executed second time from the main it is taking previous value
}
}
int main()
{
while(1)
{
demo* inst=new demo();
cout << "Value of inst "<<hex << &inst<< endl; //value is coming different from above
HANDLE threads;
DWORD threadId1;
if ((threads = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadentry,
(void *)inst, 0, &threadId1)) == NULL)
return -1;
//here is some Processing of data and after processing I close the handle
CloseHandle(threads);
delete inst;
system("pause");
}
}
No -- closing a handle to a thread does not destroy the thread itself. The thread should exit (either by calling ExitThread or by just returning from the thread function) when it's finished doing its job.
In emergencies, you can use TerminateThread to kill a thread, but that should be reserved for true emergencies -- it can leave the process in an unstable state, so it should generally be avoided, and if you have to use it, you probably want to shut down the process as soon afterwards as possible.
Also note that in a program that uses the standard library, it's not really safe to use CreateThread directly -- you should call _beginthread or _beginthreadex instead. These do some setup to allow thread-safe use of standard library functions that use static storage (e.g., strtok and mktime, but there are quite a few more).
Drop all those "(type)foo" casts, they are forcing the compiler to accept things that in reality don't fit. You will have to fix a few errors there by replacing things with the proper type. For the context pointer passed to the thread, the conversion from demo* to void* is implicit. The correct cast to reverse this is static_cast<demo*>(data). If you want, you can use the a static cast for the implicit conversion, too. There are missing return values in functions, too, the only case that is allowed is in main(). The reason I mention th s is that formally, anything can happen in your program, because these things cause undefined behaviour.
Then, you are outputting the "value of inst" but actually outputting the address of local variables called "inst", which is something different. This probably just adds to your confusion.
Now, coming to your problem, CloseHandle() does not stop the thread. It only releases your handle. What you want is WaitForSingleObject() or one of its brethren instead.
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.
I examined about stack unwinding on thread procedure in win32 environment.
My test code is the following.
class Dummy
{
public:
Dummy() { wcout << L"dummy ctor" << endl; }
~Dummy() { wcout << L"dummy dtor" << endl; }
};
void InnerFunc()
{
Dummy dm;
while(1)
{
char *buf = new char[100000000];
}
}
unsigned WINAPI ThreadFunc(void *arg)
{
Dummy dm;
try
{
InnerFunc();
}
catch(bad_alloc e)
{
wcout << e.what() << endl;
}
_endthreadex(0);
return 0;
}
void OuterFunc()
{
Dummy dm;
HANDLE hModule;
hModule = (HANDLE)_beginthreadex(0, 0, ThreadFunc, 0, 0, 0);
WaitForSingleObject(hModule, INFINITE);
CloseHandle(hModule);
}
int _tmain(int argc, _TCHAR* argv[])
{
OuterFunc();
wcout << e.what() << endl;
return 0;
}
Output result:
dummy ctor
dummy ctor
dummy ctor
dummy dtor
bad allocation
dummy dtor
As you know, an output of constructor and destructor is not paired. I think that _endthreadex() makes the thread handle be signaled and skips stack unwinding of the thread.
When I tested again without _endthreadex(), I was able to get a result I expected.
In this case, if I need stack unwinding on thread, shouldn't I use _endthreadex() in thread procedure?
I would guess the destructor is never called for the instance created in ThreadFunc. However, you should add a way to distinguish each constructor and destructor call to be sure.
Assuming that's what's happening, it seems pretty clear that endthreadex terminates the thread immediately without cleaning up the stack. The docs explicitly state that endthreadex is called when ThreadFunc returns, so why bother calling it explicitly here?
This is definitely a case where I'd use boost::thread instead. It will do the right thing in terms of thread creation and cleanup without making you worry about the win32-specific details.
Your problem is:
while(1)
{
char *buf = new char[100000000];
}
You have created a memory leak, on each iteration you create a new object losing any reference to the old object.
Stack Unwinding, clears off all the local objects in that scope,
Dummy dm;
is a object allocated on local storage inside InnerFunc(), Stack Unwinding rightly destroys this object and the single destructor call trace you see is due to this.
Stack Unwinding does not explicitly deallocate the dynamic memory. Each pointer allocated with new[] will have to be explicitly deallocated by calling a delete [] on the same address.
I don't see how it is related to any of the Windows thread functions(I am not much in to windows) but as I already stated you have a problem there.
Solution:
The simple solution to handling cleanups during exceptions is RAII.
You should use a Smart pointer to wrap your raw pointer and then the Smart pointer ensures that your object memory gets appropriately deallocated once the scope ends.
I use C++ to implement a thread class. My code shows in the following.
I have a problem about how to access thread data.
In the class Thread, I create a thread use pthread_create() function. then it calls EntryPoint() function to start thread created. In the Run function, I want to access the mask variable, it always shows segment fault.
So, my question is whether the new created thread copy the data in original class? How to access the thread own data?
class Thread {
public:
int mask;
pthread_t thread;
Thread( int );
void start();
static void * EntryPoint (void *);
void Run();
};
Thread::Thread( int a) {
mask =a;
}
void Thread::Run() {
cout<<"thread begin to run" <<endl;
cout << mask <<endl; // it always show segmentfault here
}
void * Thread::EntryPoint(void * pthis) {
cout << "entry" <<endl;
Thread *pt = (Thread *) pthis;
pt->Run();
}
void Thread::start() {
pthread_create(&thread, NULL, EntryPoint, (void *)ThreadId );
pthread_join(thread, NULL);
}
int main() {
int input_array[8]={3,1,2,5,6,8,7,4};
Thread t1(1);
t1.start();
}
I'm not familiar with the libraries you're using, but how does EntryPoint know that pthis is a pointer to Thread? Thread (this) does not appear to be passed to pthread_create.
It's great that you're attempting to write a Thread class for educational purposes. However, if you're not, why reinvent the wheel?
pThis is most likely NULL, you should double check that you're passing the correct arguments to pthread_create.
Basically, the problem is as soon as you start your thread, main exits and your local Thread instance goes out of scope. So, because the lifetime of your thread object is controlled by another thread, you've already introduced a race condition.
Also, I'd consider joining a thread immediately after you've created it in Thread::start to be a little odd.