Solved

Question on Thread control functions and availability of member variables.

Posted on 2004-10-07
6
262 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

707 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