Multithreading using AfxBeginThread
-
kartikthakre wrote:
but it is working if i am passing function pointer of any static function or global function
That is also the "classical" way to pass - for example - a private static function of a dialog... :)
// .h
...
class CYourDialog : public CDialog
{
bool m_bWorking;
CWinThread* m_pcThread;
static DWORD WINAPI ThreadProc(CYourDialog*);
...
public:
CYourDialog(CWnd* pcParent = NULL);
~CYourDialog();
...
void On();
void Off();
...
};
// .cpp
...
CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
: CDialog(CYourDialog::IDD, pcParent),
m_bWorking(false),
m_pcThread(NULL)
{
...
}
CYourDialog::~CYourDialog()
{
Off();
}
CYourDialog::On()
{
if (!m_bWorking && !m_pcThread) {
m_bWorking = true;
m_pcThread = AfxBeginThread(ThreadProc, this);
}
}
CYourDialog::Off()
{
if (m_bWorking && m_pcThread) {
m_bWorking = false;
WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
m_pcThread = NULL;
}
}
DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
{
while (pcDlg && pcDlg->m_bWorking) {
// Do something
Sleep(1);
}
return 0;
}virtual void BeHappy() = 0;
modified on Thursday, April 1, 2010 2:42 AM
Perhaps it's just a typo, but if not you should be aware of the following: There's a big risk the thread will never exit as you've failed to declare the
m_bWorking
variable asvolatile
. It depends on your optimization settings. The compiler may choose to hold the variable in a register in the while-loop, not reading it from its actual memory location since it's not being modified in the while-loop. Declaring it asvolatile
will tell the compiler that the variable must be read from its memory location and cannot be optimized into a register."It's supposed to be hard, otherwise anybody could do it!" - selfquote
"High speed never compensates for wrong direction!" - unknown -
Perhaps it's just a typo, but if not you should be aware of the following: There's a big risk the thread will never exit as you've failed to declare the
m_bWorking
variable asvolatile
. It depends on your optimization settings. The compiler may choose to hold the variable in a register in the while-loop, not reading it from its actual memory location since it's not being modified in the while-loop. Declaring it asvolatile
will tell the compiler that the variable must be read from its memory location and cannot be optimized into a register."It's supposed to be hard, otherwise anybody could do it!" - selfquote
"High speed never compensates for wrong direction!" - unknownWow, I did not know it ! Thank you very much, Roger ! :) :thumbsup: As possible "workaround" could be also the usage of a limitation function:
bool CYourDialog::IsWorking() {
return m_bWorking;
}virtual void BeHappy() = 0;
-
Wow, I did not know it ! Thank you very much, Roger ! :) :thumbsup: As possible "workaround" could be also the usage of a limitation function:
bool CYourDialog::IsWorking() {
return m_bWorking;
}virtual void BeHappy() = 0;
Eugen Podsypalnikov wrote:
Wow, I did not know it ! Thank you very much, Roger !
:) You're most welcome.
Eugen Podsypalnikov wrote:
As possible "workaround" could be also the usage of a limitation function:
bool CYourDialog::IsWorking() {
return m_bWorking;
}Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as
inline
, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly asinline
. Then you would be back to square one, with the possibility that the variable could be optimized into a register."It's supposed to be hard, otherwise anybody could do it!" - selfquote
"High speed never compensates for wrong direction!" - unknown -
Eugen Podsypalnikov wrote:
Wow, I did not know it ! Thank you very much, Roger !
:) You're most welcome.
Eugen Podsypalnikov wrote:
As possible "workaround" could be also the usage of a limitation function:
bool CYourDialog::IsWorking() {
return m_bWorking;
}Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as
inline
, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly asinline
. Then you would be back to square one, with the possibility that the variable could be optimized into a register."It's supposed to be hard, otherwise anybody could do it!" - selfquote
"High speed never compensates for wrong direction!" - unknownYes, saved... :) Thank you - for the both explanations, Roger !
virtual void BeHappy() = 0;
-
kartikthakre wrote:
but it is working if i am passing function pointer of any static function or global function
That is also the "classical" way to pass - for example - a private static function of a dialog... :)
// .h
...
class CYourDialog : public CDialog
{
bool m_bWorking;
CWinThread* m_pcThread;
static DWORD WINAPI ThreadProc(CYourDialog*);
...
public:
CYourDialog(CWnd* pcParent = NULL);
~CYourDialog();
...
void On();
void Off();
...
};
// .cpp
...
CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
: CDialog(CYourDialog::IDD, pcParent),
m_bWorking(false),
m_pcThread(NULL)
{
...
}
CYourDialog::~CYourDialog()
{
Off();
}
CYourDialog::On()
{
if (!m_bWorking && !m_pcThread) {
m_bWorking = true;
m_pcThread = AfxBeginThread(ThreadProc, this);
}
}
CYourDialog::Off()
{
if (m_bWorking && m_pcThread) {
m_bWorking = false;
WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
m_pcThread = NULL;
}
}
DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
{
while (pcDlg && pcDlg->m_bWorking) {
// Do something
Sleep(1);
}
return 0;
}virtual void BeHappy() = 0;
modified on Thursday, April 1, 2010 2:42 AM
Eugen Podsypalnikov wrote:
DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
Shouldn't this be:
UINT CYourDialog::ThreadProc( LPVOID pcDlg )
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
-
Eugen Podsypalnikov wrote:
DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
Shouldn't this be:
UINT CYourDialog::ThreadProc( LPVOID pcDlg )
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
Yes, of course :) You could use my declaration too and pass it by the casting
(AFX_THREADPROC)
, so you can use its parameterpcDlg
without casting... :)virtual void BeHappy() = 0;
-
kartikthakre wrote:
but it is working if i am passing function pointer of any static function or global function
That is also the "classical" way to pass - for example - a private static function of a dialog... :)
// .h
...
class CYourDialog : public CDialog
{
bool m_bWorking;
CWinThread* m_pcThread;
static DWORD WINAPI ThreadProc(CYourDialog*);
...
public:
CYourDialog(CWnd* pcParent = NULL);
~CYourDialog();
...
void On();
void Off();
...
};
// .cpp
...
CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
: CDialog(CYourDialog::IDD, pcParent),
m_bWorking(false),
m_pcThread(NULL)
{
...
}
CYourDialog::~CYourDialog()
{
Off();
}
CYourDialog::On()
{
if (!m_bWorking && !m_pcThread) {
m_bWorking = true;
m_pcThread = AfxBeginThread(ThreadProc, this);
}
}
CYourDialog::Off()
{
if (m_bWorking && m_pcThread) {
m_bWorking = false;
WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
m_pcThread = NULL;
}
}
DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
{
while (pcDlg && pcDlg->m_bWorking) {
// Do something
Sleep(1);
}
return 0;
}virtual void BeHappy() = 0;
modified on Thursday, April 1, 2010 2:42 AM
Thanks for reply, But i already written that it is working for static and global function. What i want is that it is work for member function. I am waiting for reply thanks
-
Is
MyThreadProc()
a static member ofCMultithreadingInDialogDlg
?"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
MyThreadProc is not a static function, it is simple member function.
-
MyThreadProc is not a static function, it is simple member function.
Which means it cannot be used an argument to
AfxBeginThread()
."One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
-
Thanks for reply, But i already written that it is working for static and global function. What i want is that it is work for member function. I am waiting for reply thanks
kartikthakre wrote:
What i want is that it is work for member function.
You can't do it directly. What you'll have to do is:
void CMyDlg::ThreadProc( void )
{
...
}UINT ThreadProc( LPVOID lpParam )
{
CMyDlg *pDlg = (CMyDlg *) lpParam;pDlg->ThreadProc(); return 0;
}
static UINT CMyDlg::ThreadProc( LPVOID lpParam )
{
CMyDlg *pDlg = (CMyDlg *) lpParam;pDlg->ThreadProc(); return 0;
}
AfxBeginThread(ThreadProc, this); // static member
AfxBeginThread(::ThreadProc, this); // global"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
-
kartikthakre wrote:
What i want is that it is work for member function.
You can't do it directly. What you'll have to do is:
void CMyDlg::ThreadProc( void )
{
...
}UINT ThreadProc( LPVOID lpParam )
{
CMyDlg *pDlg = (CMyDlg *) lpParam;pDlg->ThreadProc(); return 0;
}
static UINT CMyDlg::ThreadProc( LPVOID lpParam )
{
CMyDlg *pDlg = (CMyDlg *) lpParam;pDlg->ThreadProc(); return 0;
}
AfxBeginThread(ThreadProc, this); // static member
AfxBeginThread(::ThreadProc, this); // global"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
but what is the region, so that member function pointer is not pass to AfxBeginThread.