Solved

VC++: CWinThread for simple threads

Posted on 1998-07-16
8
2,839 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
[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
  • 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
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 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
 
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

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

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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.

627 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