Allow wxThread to access global data Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
parad0x13
Experienced Solver
Experienced Solver
Posts: 79
Joined: Tue Jan 06, 2009 3:09 am

Allow wxThread to access global data

Post by parad0x13 »

I'm having this bothersome problem when I create a thread and try to access global data. Basically I create the wxThread passing a pointer to a global class with a variable, and in the Entry() function I try to access that variable.

The problem I get every time is "Access Violation" saying that it cannot access that global class' data

- Please and thank you
illnatured
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 234
Joined: Mon May 08, 2006 12:31 pm
Location: Krakow, Poland

Post by illnatured »

This is probably because two threads try to access the variable at the same time. A simple solution is to use wxCriticalSection or wxMutex.
VC++ 2005 / Windows XP / wxWidgets 2.8.9
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Can you post some code? It's near to impossible to tell without code. Access violation generally means that your pointers are screwed up.
"Keyboard not detected. Press F1 to continue"
-- Windows
parad0x13
Experienced Solver
Experienced Solver
Posts: 79
Joined: Tue Jan 06, 2009 3:09 am

Post by parad0x13 »

Absolutely, thank you for your attention

Simple format of the code I'm talking about:

part of main.cpp

Code: Select all

	Pointers *pointers = new Pointers();
	pointers->ScreenResolution = ::wxGetDisplaySize();

	pointers->tempAccess = new temp;
Pointers.h

Code: Select all

#ifndef _POINTERS_
#define _POINTERS_

class RenderGLCanvas;
class temp;

class Pointers
{
public:
	RenderGLCanvas *RenderCanvas;
	temp *tempAccess;

	wxSize ScreenResolution;
};

#endif
CalculateThread.h

Code: Select all

#ifndef _CALCULATETHREAD_
#define _CALCULATETHREAD_

#include "wx.h"
#include "Pointers.h"

#include "temp.h"

DECLARE_EVENT_TYPE(wxEVT_THREAD, -1)

class CalculateThread : public wxThread
{
public:
	CalculateThread(wxEvtHandler *ehParent, Pointers *pointer, int equation){m_ehParent = ehParent;Equation = equation;};
	~CalculateThread(){};

private:
	int Equation;
	void *Entry();
	Pointers *global;
	wxEvtHandler *m_ehParent;
};

#endif
CalculateThread.cpp

Code: Select all

#include "CalculateThread.h"
#include "enum.h"

void *CalculateThread::Entry()
{
	// Why will this not write to memory!
	//IFS.SierpinskiTriangleCoords();

	int test = global->tempAccess->value;
	//global->tempAccess->value = 5;
	//if(temp.value == 2)
	//	exit(0);

	wxCommandEvent evt(wxEVT_THREAD, wxID_ANY);
	evt.SetId(ID_Thread_Render);
	m_ehParent->AddPendingEvent(evt);

	return NULL;
};
some function somewhere

Code: Select all

global->tempAccess->value = 2;
wxThread *test = new CalculateThread(this, global, ID_SierpinskiTriangle);
		test->Create();
		test->Run();
Now, the global variable to the PointerClass has been passed to the CalculateThread initializer seen in the last bit of code that I pasted, this thread runs Entry() which tries to access the variable data in the global temp class by means of assigning integer 'test' that value, this is where everything goes wrong... oh so very wrong
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Can you show what "global" is? Beyond being quite an ugly way to do things, I also suspect you did the same mistake as in the other thread : statics in a header

EDIT:
Seems like the thread receives the object as argument but doesn't do anything with it :

Code: Select all

CalculateThread(wxEvtHandler *ehParent, Pointers *pointer, int equation){m_ehParent = ehParent;Equation = equation;}; 
"Keyboard not detected. Press F1 to continue"
-- Windows
parad0x13
Experienced Solver
Experienced Solver
Posts: 79
Joined: Tue Jan 06, 2009 3:09 am

Post by parad0x13 »

global is just a variable that points to the global Pointer class that is declared in main.cpp

main.cpp

Code: Select all

#include "main.h"
#include "wxVertigo_Frm.h"
#include "Pointers.h"
#include "rand.h"

#include "temp.h"

IMPLEMENT_APP(MainApp)

bool MainApp::OnInit()
{
	initImageHandlers();
	seed();	// Seed random generator

	Pointers *pointers = new Pointers();
	pointers->ScreenResolution = ::wxGetDisplaySize();

	pointers->tempAccess = new temp;

	wxVertigo_Frm *wxVertigo = new wxVertigo_Frm(wxT("wxVertigo"), *pointers);
	wxVertigo->Show(true);
	wxVertigo->Maximize(true);

	return true;
}

void MainApp::initImageHandlers()
{
	wxImage::AddHandler(new wxPNGHandler());
};
I'd like to know a cleaner not-so-ugly way of doing it, but this is the only way I know how!

The thread reads the global made class "temp" from the global pointer and tries to read it, but can't.

Please show me a better way of doing this!

Edit*

And I see what you mean by not initializing global from the initializer that was passed to the thread, I did such:

Code: Select all

CalculateThread(wxEvtHandler *ehParent, Pointers *pointer, int equation)
	{
		m_ehParent = ehParent;
		global = pointer;
		Equation = equation;
	};
and now it wont cry when I try to access the variable, but it still wont write to it
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Code: Select all

        wxVertigo_Frm *wxVertigo = new wxVertigo_Frm(wxT("wxVertigo"), *pointers); 
What is the signature of the wxVertigo_Frm constructor? I don't quite get why you are passing "*pointers", are you passing by copy?
"Keyboard not detected. Press F1 to continue"
-- Windows
parad0x13
Experienced Solver
Experienced Solver
Posts: 79
Joined: Tue Jan 06, 2009 3:09 am

Post by parad0x13 »

signature? I'm not quite sure what you mean. The only way I know how to pass global variables, like the Pointers class that I initiated in main.cpp, would be by pointer assigning when I call a function

If there's a better way please tell!
frank_frl
Earned some good credits
Earned some good credits
Posts: 139
Joined: Sat Feb 18, 2006 1:41 pm
Location: Germany

Post by frank_frl »

Hi parad0x13,

there is a nice class in wxWidgets to make things like this easy.
http://docs.wxwidgets.org/stable/wx_wxthreadhelper.html

Frank
WinXp SP3, OS X10.5.5; CodeLite, Dialog::Blocks, wxWidgets 2.8.10
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

parad0x13 wrote:signature? I'm not quite sure what you mean.
The function with its list or arguments (what you'd put in a header)
"Keyboard not detected. Press F1 to continue"
-- Windows
Post Reply