Solved

VC++: CWinThread for simple threads

Posted on 1998-07-16
8
2,739 Views
Last Modified: 2008-02-01
Hi,

I'd like to use CWinThread to create a simple, worker thread. I've used AfxBeginThread in the past, but CWinThread seems more encapsulated. This is probably really easy, but as usual the documentation in Visual C is horrible and I can't make heads or tails out of it.

What I'm doing is creating a derivation of CWinThread called CThinker with an overridden Run(). Whenever I want a thread I create a new CThinker object and call CreateThread, which returns TRUE, but somehow my Run() function never gets called.

What am I doing wrong? If this turns out to be more complicated then I think, I will add points.
0
Comment
Question by:Slarti
  • 5
  • 3
8 Comments
 
LVL 7

Expert Comment

by:galkin
ID: 1167965
If you want to crate a worker thread user other version of overloaded function AfxBeginThread that is passed pointer to thread entry point function. As this function returns worker thread exits. If you create UI thread derive class from CWinThread. run virtual function contains message pump for all windows created from current thread. This message pump exits when thread is sent WM_QUIT message generally when main window is closed. When message pump exits, Run returns then ExitInstance is called and thread is terminated.  
0
 
LVL 2

Author Comment

by:Slarti
ID: 1167966
galkin,
You didn't really answer my question. As I said, I already know how to use AfxCreateThread to create worker threads. I want to avoid this. What I want is to create a worker thread which is derived from CWinThread. According to the documentation, this should be possible, but there are not examples that I could find on how to do this.
By the way, it is incorrect that "As this function [AfxCreateThread] returns worker thread exits". AfxCreateThread returns immediately after the worker thread begins working. The thread then terminates without notifying its creator.
0
 
LVL 2

Author Comment

by:Slarti
ID: 1167967
galkin,
You didn't really answer my question. As I said, I already know how to use AfxCreateThread to create worker threads. I want to avoid this. What I want is to create a worker thread which is derived from CWinThread. According to the documentation, this should be possible, but there are not examples that I could find on how to do this.
By the way, it is incorrect that "As this function [AfxCreateThread] returns worker thread exits". AfxCreateThread returns immediately after the worker thread begins working. The thread then terminates without notifying its creator.
0
 
LVL 7

Expert Comment

by:galkin
ID: 1167968
It terminates because your worker thread doesn't contain any windows so message pump implemented in Run function exits immediately so thread is terminated.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 2

Author Comment

by:Slarti
ID: 1167969
But I've overridden the Run function entirely, and it never even gets called.
Can you give me a simple, step-by-step list of instructions on what to do to get a worker thread to run when it is derived from CWinThread?

0
 
LVL 7

Accepted Solution

by:
galkin earned 30 total points
ID: 1167970
It is not called because you didn't override InitInstance function that by default returns FALSE and Run is never called. I rsuggest you stepping into AfxBeginThread and looking at how it works.
0
 
LVL 2

Author Comment

by:Slarti
ID: 1167971
I will do that and get back to you.
0
 
LVL 2

Author Comment

by:Slarti
ID: 1167972
Well, that's not much of an answer, but it did lead me to the correct answer eventually. Since I am in the habit of documenting such problems for my own later use, I am attaching a description of the problem and solution for people who use this as a PAQ.

Incomplete Entries in the Online Help
 ·  Undocumented CWinThread constructor. CWinThread has two constructors. The first, CWinThread::CWinThread(), receives no parameters and does not initialize the function pointer within it. This constructor is documented briefly. The second constructor is undocumented and is the more commonly used constructor (it is used by AfxBeginThread). Here is a description.
  CWinThread::CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam)
  Constructs a CWinThread object, and sets the thread procedure to pfnThreadProc and the parameter which is passed to this thread procedure to pParam. This constructor, together with the CWinThread::CreateThread() function, is identical to using the worker thread version of AfxCreateThread, except that AfxCreateThread performs some error checking and also has a version for non-multitasking compilations. For an example of the use of this constructor to create and execute a thread, see the source for AfxCreateThread, in mfc\src\thrdcore.cpp, line 151.
 ·  Incomplete documentation for CWinThread::m_bAutoDelete. In the help entry for CWinThread::m_bAutoDelete (search for m_bAutoDelete in the help index), the default value is not mentioned. The default value is TRUE. The use of m_bAutoDelete is described in more detail in the article Multithreading: Terminating Threads in the online help.
 ·  Detailed instructions for creating worker threads derived from CWinThread. The online help recommends using AfxBeginThread to create worker threads, but this requires the creation of a global function for the thread procedure, which violates information hiding and encapsulation. One can also create worker threads by deriving a class from CWinThread. Follow the following instructions:
  1 . Derive a class from CWinThread. There is no need to call the CWinThread constructor from the derived constructor. Override the function CWinThread::Run() to contain whatever you want the thread to do. If your class contains any data members, declare a virtual destructor, even if you leave it empty (see step 5).
  2 . Override the function CWinThread::InitThread() so that it always returns TRUE. This tells the CWinThread initialization routines to call Run(). If InitThread() returns FALSE for some reason, the thread will terminate immediately, before calling Run(). No error message will be displayed. (This is what happened to me.)
  3 . Before beginning the thread, dynamically construct an object of the derived type using operator new. Dynamic allocation is very important, because the object will be deleted by the thread itself and local objects cannot be deleted by other threads.
  4 . To begin a thread, call the object’s member function CreateThread(). The object can be constructed at any point; the thread begins executing only when CreateThread() is called. Different objects can be used to create simultaneous threads using the same Run() function.
  5 . The thread terminates when Run() returns. The object is then deleted automatically by the encapsulating CWinThread functions, which is why you should declare a virtual destructor, even if it does nothing.

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

746 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now