I am creating 5 thread here using ThrdFunc. Here each thread update the listBox.
I was expecting message in this way. Initially come in this way but after some time
Thread1:Adding msg
Thread2:Adding msg
Thread3:Adding msg
But after some time I get message like
Thread0:Adding msg
Thread18967654:Adding msg
Thread18967654:Adding msg
Thread18967654:Adding msg
This is the code:
for (int i = 0;i<6;i++)
{
nThreadNo = i+1;
hWndProducer[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ProducerThrdFunc,(void*)&nThreadNo,0,&dwProducerThreadID[i]);
if (hWndProducer[i] == NULL)
{
//ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
}
DWORD WINAPI ThrdFunc ( LPVOID n )
{
int *nThreadNo = (int*)n;
char chThreadNo[3];
memset(chThreadNo,0,3);
while(1)
{
itoa(*nThreadNo,chThreadNo,10);
char* pMsg1 = new char[100];
char* pMsg2 = new char[100];
memset(pMsg1,0,100);
memset(pMsg2,0,100);
strcpy(pMsg1," Thread No:");
strcat(pMsg1,chThreadNo);
strcat(pMsg1," Adding Msg:");
PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg1,0);
}
return 0;
}
Most likely nThreadNo is allocated on the stack. You're giving each thread a pointer to one of it's elements.
Once the function creating the threads returns, the array is no longer valid, but the thread functions are still pointing to it. The memory the threads are holding pointers to will most likely be overwritten, causing what was originally the thread ID to be overwritten with garbage.
Anything you pass another thread should generally be allocated on heap, either via malloc type functions or new, preferably new since this is C++.
For example, instead of int nThreadNo[6], use int* nThreadNo = new int[6]. However, keep in mind that you will have to delete[] the memory nThreadNo points to when you're done with it.
Well, I can't be sure because you've not given all your code.
However, it looks like nThreadNo is a local variable, defined on the stack of the main thread. You are passing the address of this variable to the threads, but you should be passing the value, or passing some heap allocated memory.
What you are doing is morally equivalent to returning from a function a pointer to a local variable, e.g.
int* foo()
{
int i;
return &i;
}
The simplest way to make your code behave is to make the following changes:
CreateThread(..., (void*)nThreadNo, ...
int nThreadNo = (int)n;
nThreadNo has to be global because you are giving a pointer to it to your new thread.
Related
Our code has just started crashing due to a thread calling a memory alloc function and losing the pointer to the memory pool.
The pointer is initialised before the threads are started, but when the thread uses it to call the memory alloc code, it's zero.
In out init code we have
poolptr = InitMemoryPool ()
This sets it to a non zero memory address
In our .mm code on the thread we have
unsigned byte * p=(unsigned byte * ) MyAlloc ( poolptr, amount )
When the code gets into the MyAlloc function, poolptr is 0
Do I need my poolptr pointer to be volatile ? Even so, it's value is set up before the thread starts and never changes, so if the compiler is assuming it's a const, why doesn't it have it set correctly ?
Also, this has worked fine for years - and just started going wrong yesterday, simultaneously on two peoples machines.
Any ideas ?
This, what you mentioned, I don't do. What eventually worked for me is as follows:
I call my function or method and put in that function or method local instances of an class on the heap via command "new". Data that is to be returned is also paid respect to. Triggering a new thread will have access to that heap area if the heap area is a simple parameter. I.e., t= new thread( parameter);
void* function_or_method() {
clist *lstp;
string *_ps;
bool b;
try {
lstp= NULL;
lstp= new clist;
_ps= new string;
lstp->set( (void *)_ps);
mathclass *math;
thread *_thread;
math= new mathclass();
if((NULL==math))
throw Exception();
b= math->set( lstp);
if(! b) {
throw Exception();
}
_thread= new thread( math);
_thread->join();
delete _thread;
_thread= NULL;
} catch(const exception& e) {
clog <<"exception: logging" <<endl;
}
return (void*)lstp;
}
Okay, this is just C++ as well as C. I hope it will help a bit.
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.
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'm having a problem calling a thread more than once and the variables messing up. I'm new to threads, so I'm sure I'm missing something simple.
struct PARAMS
{
time_t secondsAtStart;
};
DWORD WINAPI ProcessChange(void* parameter) {
PARAMS* params = (PARAMS*)parameter;
Sleep(3000);
_tprintf(TEXT("Seconds: (%d)\n"), params->secondsAtStart);
return 0;
}
void FileChanged(CString filename, CString action) {
struct PARAMS *params = NULL;
params = (struct PARAMS *)malloc(sizeof(PARAMS)+1);
params->secondsAtStart = time(null);
// I've also tried it this way.
//PARAMS params;
//params.secondsAtStart = time(NULL);
HANDLE hThread = CreateThread(NULL, 0, ProcessChange, ¶ms, 0, NULL);
// If I uncomment this, it works, but just one thread runs at a time.
//WaitForSingleObject(hThread, INFINITE);
}
If I don't uncomment the WaitForSingleObject, then the secondsAtStart variable gets corrupted. The end result I need is that if FileChanged gets called 3 times right after one another, I'm going to have the first two runs do nothing and the last one do the action.
Thanks,
Ben
Passing addresses of (or references to) local variables of a function, i.e. variables of automatic storage, to a thread causes undefined behaviour if the thread lives longer than the function.
In your code, params points to an object of dynamic storage, but the pointer itself is a local variable. You pass its address ¶ms to the thread. This only works if by waiting for the thread to finish you guarantee the pointer lives longer than the thread. Otherwise it causes undefined behaviour, which quite naturally manifests itself in nonsensical values being printed.
Passing params instead of ¶ms should solve the problem. (Also note that the code as written causes a memory leak; you'll need to make sure you actually free the space allocated after the thread has finished.)
This question is a refinement of this one, which went in a different direction than expected.
In my multithreaded application, the main thread creates parameters and stores them:
typedef struct {
int parameter1;
double parameter2;
float* parameter3;
} jobParams;
typedef struct {
int ID;
void* params;
} jobData;
std::vector<jobData> jobs;
// main thread
for (int i = 0; i < nbJobs; ++i) {
jobParams* p = new jobParams;
// fill and store params
jobData data;
data.ID = i;
data.params = p;
jobs.push_back(data);
}
// start threads and wait for their execution
// delete parameters
for (int i = 0; i < jobs.size(); ++i) {
delete jobs[i].params;
}
Then, each thread gets a pointer to a set of parameters, and calls a job function with it:
// thread (generic for any job function and any type of params)
jobData* job = main->getNextParams();
jobFunction(job->ID, job->params);
The whole thing takes void* as argument to be able to use any structure for the parameters, but then the job function casts it back to the right struct:
void* jobFunction(void* param) {
jobParams* params = (jobParams*) param;
// do stuff
return 0;
}
My problem is the following: if I delete params at the end of jobFunction(), it works perfectly. However, I'd prefer to have the deletion taken care of by the threads or the main thread, such that I don't have to remember to delete the params for each jobFunction() that I write.
If I try to delete params just after calling jobFunction() in the treads, or even in the main thread after being sure that all threads are done (and thus the params are not needed anymore), I get a heap corruption error:
HEAP[prog]: Invalid Address specified to RtlFreeHeap( 02E90000, 03C2EE38 )
I'm using Visual Studio 2008 Pro, and I thus can't use valgrind or other *nix tools for debugging. All access to the main thread from the "child threads" are synchronized using a mutex, so the problem is not that I delete the same parameters twice.
In fact, by using VS memory viewer, I know that the memory pointed by the jobParams pointer does not change between the end of jobFunction() and the point where I try to delete it (either in the main thread or in the "child threads").
I added the definition of both structures, as well as the way I'd like to delete the params.
Just as a thought .. can you try
for (int i = 0; i < jobs.size(); ++i) {
delete (jobParams*)jobs[i].params;
}
newing a type jobParams and then deleteing a void* might be the cause of your problems.
Is there any reason you store params as a void* in jobData? I'd argue if you wish to have different types of jobParams then you should be using an inheritance hierarchy and not blindly casting to a void*.
That sort of bug generally means you have a data race somewhere. Does main->getNextParams() do the right thing even if it's called by several threads at once? If it gives the same params to both, you could have a double-free in your hands.
Also, instead of
jobFunction(jobData->ID, jobData->params);
You probably meant
jobFunction(job->ID, job->params);
To debug it you could add a deleted member to the jobParams class and set that to true instead of actually deleting the object. Then see check the deleted flag in every method of jobParams and throw an exception if it's true. Then see where the exception gets thrown.