Problems with threads
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
Problems with threads
Hi All,
In my app, i am creating a thread to run some process. This thread is created with wxThreadHelper class and OnDialogActivate of a modal dialog created in the application.
Once the thread has done processing, EndModal(wxID_OK) is called and the dialog is destroyed. Now, my application has a menubar to launch this dialog. After clicking and successfully terminating the dialog 10-15 times my app crashes with following in GDB:
GThread-ERROR **: file /build/buildd/glib2.0-2.16.6/gthread/gthread-posix.c: line 367 (g_thread_create_posix_impl): error 'Cannot allocate memory' during 'pthread_create'
aborting...
When i put Debug logs in my code it looks like there was thread creation error:
if(wxThreadHelper::Create()==wxTHREAD_NO_ERROR)
This condition returns false.
Please help me as to what is wrong in this...
In my app, i am creating a thread to run some process. This thread is created with wxThreadHelper class and OnDialogActivate of a modal dialog created in the application.
Once the thread has done processing, EndModal(wxID_OK) is called and the dialog is destroyed. Now, my application has a menubar to launch this dialog. After clicking and successfully terminating the dialog 10-15 times my app crashes with following in GDB:
GThread-ERROR **: file /build/buildd/glib2.0-2.16.6/gthread/gthread-posix.c: line 367 (g_thread_create_posix_impl): error 'Cannot allocate memory' during 'pthread_create'
aborting...
When i put Debug logs in my code it looks like there was thread creation error:
if(wxThreadHelper::Create()==wxTHREAD_NO_ERROR)
This condition returns false.
Please help me as to what is wrong in this...
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
Ok I guess i have identified my issue and here it is with further details:
I have my thread class defined as
MyThread:public wxThreadHelper.
In my another dialog init code, a new object of MyThread is created as:
MyThread *thread = new MyThread;
In the constructor of MyThread, i create one object for another class and two other (one of wxMutex and wxCondition).
In ~MyThread Destructor, i am deleting all the above objects created in the constructor. When i debug through the code and when i am in the destructor, i notice that even after delete is called on all objects, memory associated with them is not released .
Additionally, in the destructor of my custom dialo, i delete thread object. However, even that is not released and there are no errors until memory is full and no more threads can be created!.
I have my thread class defined as
MyThread:public wxThreadHelper.
In my another dialog init code, a new object of MyThread is created as:
MyThread *thread = new MyThread;
In the constructor of MyThread, i create one object for another class and two other (one of wxMutex and wxCondition).
In ~MyThread Destructor, i am deleting all the above objects created in the constructor. When i debug through the code and when i am in the destructor, i notice that even after delete is called on all objects, memory associated with them is not released .
Additionally, in the destructor of my custom dialo, i delete thread object. However, even that is not released and there are no errors until memory is full and no more threads can be created!.
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
ok here is my code
Now, let's look inside My Thread
The Thread is now run hence let's look at Entry Method:
In the above function, EvtData is another class that Locks the mutex in the constructor and unlocks it in the desctuctor (~EvtData). Event is posted to the main thread and Wait() method waits on the condition.
Once the event is processed this thread is signaled.
Let's look at the destructor:
That's all i have in my application. Even if I call delete memory is not released.[/code]
Code: Select all
//This function is in my dialog that is launched on menu event. (File->Start Thread)
void MyDialog::InitMyThread()
{
MyThread::myobj = myClass; //here myClass is someother class in my application
MyThread::arrayList = list;//arrayList and list are wxArrayPtrVoid
MyThread::myappObj = this;
MyThread::boolVar = false;
thread = new MyThread;
thread->Run();
}
Code: Select all
MyThread::MyThread(): wxThreadHelper()
{
anotherClass = new anotherClass();//anotherClass is declared private in MyThread.h
m_mutex = new wxMutex();
m_condition = new wxCondition(*m_mutex);
}
Code: Select all
void* MacThread::Entry()
{
EvtData evtData(m_mutex, m_condition);
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED , ID_MYID);
evt.SetClientData((void *) &evtData);
::wxPostEvent(myappObj,evt);
m_condition->Wait();
return NULL;
}
Once the event is processed this thread is signaled.
Let's look at the destructor:
Code: Select all
MacThread::~MacThread()
{
delete anotherClass;
delete m_condition;
delete m_mutex;
}
i assume MyThread and MacThread are the same, you just forgot to rename one of them?
are these really static variables? why?
wxThreadHelper doesn't have a Run() method? If you edit your code to make it easier to understand, please don't make a guessing game out of it.
that's wrong, the pointer to evtData will be invalid by the time it's processed.
I assume there is some processing part missing? A thread that just sends a message is not very useful.
Code: Select all
MyThread::myobj = myClass; //here myClass is someother class in my application
MyThread::arrayList = list;//arrayList and list are wxArrayPtrVoid
MyThread::myappObj = this;
MyThread::boolVar = false;
Code: Select all
thread = new MyThread;
thread->Run();
Code: Select all
EvtData evtData(m_mutex, m_condition);
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED , ID_MYID);
evt.SetClientData((void *) &evtData);
::wxPostEvent(myappObj,evt);
m_condition->Wait();
return NULL;
I assume there is some processing part missing? A thread that just sends a message is not very useful.
Use the source, Luke!
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
Yes, they are static variables as myappObj needs to be shared between threads and so for other variables.
Also MacThread = MyThread;
I missed my Run method here it is:
Well as far as processing is concerned, I have similar events one after the other.
I understand that the EvtData will be invalid by the time event is processed and hence I am waiting on the event to be processed. Like i said this thread (MyThread) will keep on waiting for the event to be processed.
Once the event is processed, wxConfition will be signaled and MyThread will resume to send out next event.
Also MacThread = MyThread;
I missed my Run method here it is:
Code: Select all
void MyThread::Run()
{
if(wxThreadHelper::Create()==wxTHREAD_NO_ERROR)
{// create thread
GetThread()->Run();
}
}
I understand that the EvtData will be invalid by the time event is processed and hence I am waiting on the event to be processed. Like i said this thread (MyThread) will keep on waiting for the event to be processed.
Once the event is processed, wxConfition will be signaled and MyThread will resume to send out next event.
that's a little weird way of doing things, but nevertheless i don't see an obvious memory leak.
where does thread get destroyed? Did you confirm that the thread dtor is actually executed?
Code: Select all
thread = new MyThread;
thread->Run();
Use the source, Luke!
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
http://docs.wxwidgets.org/stable/wx_wxt ... l#wxthread
Try calling Wait() on the thread before destroying it.
wxThreadHelper internally creates a joinable thread, so i guess this is somehow the reason for your error.You shouldn't hurry to create all the threads joinable, however, because this has a disadvantage as well: you must Wait() for a joinable thread or the system resources used by it will never be freed, [...]
Try calling Wait() on the thread before destroying it.
Use the source, Luke!
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
-
- Filthy Rich wx Solver
- Posts: 205
- Joined: Wed Jun 25, 2008 3:37 pm
Delete() only works when your thread runs in a loop and calls TestDestroy() frequently.
If the thread waits for a condition like in your case, you can have to use wxThread::Kill()
http://docs.wxwidgets.org/stable/wx_wxt ... threadkill
If the thread waits for a condition like in your case, you can have to use wxThread::Kill()
http://docs.wxwidgets.org/stable/wx_wxt ... threadkill
Use the source, Luke!