Solved

Question on Thread control functions and availability of member variables.

Posted on 2004-10-07
6
257 Views
Last Modified: 2008-02-26
If I launch a thread from within an object:

m_pThread = AfxBeginThread(ThreadProcessProc, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL );

and define my ThreadProcessProc as follows:

UINT CVideoCapture::ThreadProcessProc( LPVOID a_pParam )
{
    CVideoCapture* pInstance = (CVideoCapture*) a_pParam;
    // ...
}

Here I've passed "this" as the param to the control function, and so within the ThreadProcessProc method, I cast a_pParam to (CVideoCapture*) so that the calling object is availalbe within the thread's controlling function.

This is correct so far right?

I'm still a bit confused though, if I want to access any member variables or functions defined in the calling object, do I have to do so via this pointer to the calling object?

For example, say the object that is launching the thread has a member variable m_pSomeMember, and an accessor for that called GetSomeMember(). Within my thread control function, if I want to access m_pSomeMember, do I have to do this:

   if ( pInstance->GetSomeMember() == 1 )

or can I access it directly like this:

  if (m_pSomeMember == 1)


Is this where static members come into play? If I want direct access to a member variable from within a thread controlling function, I have to declare it statically, ie.

    BOOL   CVideoCapture::m_bKillThread;

CVideoCapture::CVideoCapture()  // constructor
{
}

What if the member variable my thread control function needs access to is not static? Do I need to implement an accessor method for it which I'd call via the local pInstance reference I cast from the a_pParam?

I hope this makes sense! I'm still just a bit confused.

-Paul
0
Comment
Question by:PMH4514
  • 4
  • 2
6 Comments
 
LVL 14

Accepted Solution

by:
wayside earned 50 total points
ID: 12249862
First, thread functions need to be declared as static.

Second, because thread functions are static, they have no "this" pointer. You are passing in an object pointer via the parameter and casting it to what you want. So you must use it to access all of the members of the objects. Your statement:

> do I have to do this:

>    if ( pInstance->GetSomeMember() == 1 )

is correct, that's how you have to do it.

If you just try

>  if (m_pSomeMember == 1)

it won't compile because there is no "this" pointer in this function. You would have to do

if (pInstance->pSomeMember == 1)

assuming pSomeMember is declared as public.



0
 
LVL 14

Expert Comment

by:wayside
ID: 12249900
> If I want direct access to a member variable from within a thread controlling function, I have to declare it statically

No, you use the param passed in as the argument and cast to the object you need. Then you can access any public members of the object just as you would with any object pointer, i.e.

pInstance->pSomeMember

or

pInstance->GetSomeMember()

I hope this is clear...
0
 

Author Comment

by:PMH4514
ID: 12250048

>>First, thread functions need to be declared as static.

yup, I got that.. I showed the implementation of it actually, this is how it's defined in the header:

static UINT ThreadProcessProc( LPVOID a_pParam );

>>is correct, that's how you have to do it.
ok, so I was on the right track.. I was confused because an example I was looking at was setting a m_pKillThread member variable to true at a certain point, and I thought "why can the control function access that member variable on its own?" but then I discovered that m_pKillThread was also declared static.


>>No, you use the param passed in as the argument and cast to the object you need.
>>Then you can access any public members of the object just as you would with any object pointer,

ok this makes total sense. So is it pretty much "convention" to pass "this" as the paramater to the controlling function? "this" of course being a reference to the object that is launching the thread? Or does it totally depend on context and what the thread is doing? My first inclination was to define a struct that held references to all of the launching objects variables that I would need access to, but passing "this" and using accessors does seem much more clear.

>>I hope this is clear...
perfectly, answered my questions exactly. Thanks!

-Paul

0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 14

Expert Comment

by:wayside
ID: 12250403
> So is it pretty much "convention" to pass "this" as the paramater to the controlling function?

It is convention? I don't know, I do it a lot though. It depsnds on what you need to do in the thread.

A lot of times I need more than one piece of data in the thread function, so I have helper classes to package them up:

class PtrPair {
public:
  PtrPair() {i=j=NULL;}
  PtrPair(void *m, void *n) { i=m; j=n; }
  PtrPair(const class PtrPair &p) { i=p.i; j=p.j; }
  void *i,*j;
};

Then I would do something like:

m_pThread = AfxBeginThread(ThreadProcessProc, new PtrPair(this, p_otherptr), THREAD_PRIORITY_NORMAL, 0, 0, NULL );

and in the thread func:

UINT CVideoCapture::ThreadProcessProc( LPVOID a_pParam )
{
   PtrPair pPair = (PtrPair *)a_pParam;
   CVideoCapture* pInstance = (CVideoCapture*) (pPair.i);
   COtherObject* pOtherObj = (COtherObject *)(pPair.j);
   delete pPair;

...
}

I have a bunch of these for different numbers of arguments.
   
0
 

Author Comment

by:PMH4514
ID: 12253183
nice, that's basically what I had envisioned.. only I was thinking some kind of typedef struct.. same difference though right?
0
 
LVL 14

Expert Comment

by:wayside
ID: 12253737
Yup. Making it a class lets you create them in line, which I find more convenient, because classes have constructors.

0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Connecting to MS SQL db from Win32 application written in C 3 85
Grammars for C C++ and java 1 122
Embarcadero C++ Builder XE2 TDateTime 8 70
designing in object programming 12 75
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question