-
October 1st, 2014, 12:53 PM
#1
Calling a function in AfxBeginThread
I have the code:
void go(CMFCApplication1Dlg * pdlg)
{
pdlg->listcontrol1.InsertItem(0, "Row1");
}
then i call it in thread
Code:
void CMFCApplication1Dlg::OnBnClickedButton3()
{
AfxBeginThread(go(this), NULL, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
}
It doesn't work. Any idea how to make it work ? Thanks in advance!
-
October 1st, 2014, 02:00 PM
#2
Re: Calling a function in AfxBeginThread
Well, better would be to forget what and how you wrote and instead learn about Using Worker Threads from the very begin!
Victor Nijegorodov
-
October 2nd, 2014, 06:46 AM
#3
Re: Calling a function in AfxBeginThread
DO NOT attempt to create, modify, delete or basically do anything with windows on anything other than your main thread.
threads are for running non UI related code. UI related code belongs (strangely Obvious) in the main UI thread.
If you want to get somethign displayed from the worker thread, then POST (not send) a message to tell the main thread to do that work on behalf of the worker thread.
This is a fundamental premise in Windows. If you insist on updating the UI directly from a worker thread, expect to get crashes, deadlocks and all around strange behaviour at irregular moments during your program's run time.
-
October 2nd, 2014, 07:20 AM
#4
Re: Calling a function in AfxBeginThread
If you insist on updating the UI directly from a worker thread, expect to get crashes, deadlocks and all around strange behaviour at irregular moments during your program's run time.
Here, here! I'm still getting the nightmares from debugging some one's code that did this. The program used to randomly crash with memory exception problems. Very nasty.
This advice applies whether you use WIN32 APIs or MFC or another framework.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
October 2nd, 2014, 02:56 PM
#5
Re: Calling a function in AfxBeginThread
Well, unlike MFC, Win32 API is completely thread safe. Though deadlocks are possible in any sort of threads, worker or GUI ones. And avoiding those is just a matter of understanding root cause.
Best regards,
Igor
-
October 2nd, 2014, 03:06 PM
#6
Re: Calling a function in AfxBeginThread
Originally Posted by Igor Vartanov
Well, unlike MFC, Win32 API is completely thread safe. Though deadlocks are possible in any sort of threads, worker or GUI ones. And avoiding those is just a matter of understanding root cause.
I've found issues with UI in WIN32 API code where more than one thread has been updating directly the UI. Changing the logic to that described by OReubens in post #3 cured the intermittent program crashes. Of course, in changing the code like that I may have fixed the underlying thread issues that caused the problem in the first place...........
IMO I would still recommend that the program design adheres to the principle outlined in post #3.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
October 2nd, 2014, 03:10 PM
#7
Re: Calling a function in AfxBeginThread
Originally Posted by eclessiastes
I have the code:
then i call it in thread
Code:
void CMFCApplication1Dlg::OnBnClickedButton3()
{
AfxBeginThread(go(this), NULL, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
}
It doesn't work. Any idea how to make it work ? Thanks in advance!
You should not call MFC windowed objects from thread other than the one those were created in. Add a string data member to your dialog, add a handler to a special window message that would call that InsertItem for list control. In your worker thread you should assign the string some value and post the message to dialog window using plain Win32 API PostMessage. No calls of MFC window object methods accross thread bounds.
Best regards,
Igor
-
October 3rd, 2014, 03:21 AM
#8
Re: Calling a function in AfxBeginThread
Originally Posted by Igor Vartanov
...Add a string data member to your dialog, add a handler to a special window message that would call that InsertItem for list control. In your worker thread you should assign the string some value and post the message to dialog window using plain Win32 API PostMessage. No calls of MFC window object methods accross thread bounds.
...and synchronize access to the string data member using a Critical Section.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
October 3rd, 2014, 07:15 AM
#9
Re: Calling a function in AfxBeginThread
Originally Posted by Igor Vartanov
Well, unlike MFC, Win32 API is completely thread safe. Though deadlocks are possible in any sort of threads, worker or GUI ones. And avoiding those is just a matter of understanding root cause.
Well... I guess it depends on what you would call "thread safe". The answer is not as clear cut as it seems.
from a pure technical POV. Yes, you are right...
IN practice things are a bit more complex, because the UI type API's typically expect that you use a window handle ONLY on the same thread that created the window handle in the first place, which also needs to be the very same thread where the window procedure will be called on.
Does that invalidate the "thread safety" assumption ? No, because it is possible to have more than one UI thread. But really, this is a whole other can of worms you're opening if you insist on needing more than 1 UI thread. So yes, the API's are technically safe because you can call the same UI related function from 2 UI threads at the same time PROVIDED each thread is handling an window that "belongs to" its own thread.
--
And yes, there are a few cases where you can seemingly get this to work reliably for all flavours of Windows. "the magic" is in the way SendMessage() works.
Note the remarks on there however "The sending thread is blocked until the receiving thread processes the message. "
With proper care you can make this to work, but later changes can easily disrupt the assumptions made to get it to work. It's much better to simply approach your app from the premise that you shouldn't touch the UI directly from a worker thread.
This in and of itself is one of the most common "bugs" I'm finding in software I'm evaluating.
-
October 3rd, 2014, 02:51 PM
#10
Re: Calling a function in AfxBeginThread
Originally Posted by OReubens
Well... I guess it depends on what you would call "thread safe". The answer is not as clear cut as it seems.
from a pure technical POV. Yes, you are right...
IN practice things are a bit more complex, because the UI type API's typically expect that you use a window handle ONLY on the same thread that created the window handle in the first place, which also needs to be the very same thread where the window procedure will be called on.
All Windows UI API is built mostly on sending messages to controls, and one really critical thing you are to remember about is "SendMessage blocks caller thread". All the other APIs dealing with window handles are perfectly thread safe, maybe with a few rare exceptions related to message queue pumping specifics.
All the said above gives us totally different picture. Once again, UI related Win32 API is thread safe by design, maybe with a few rare exceptions. And all troubles with MFC window objects have nothing to do with Win32 API, being stipulated by the very specific way how MFC maps native window handles to corresponding MFC CWin-derived objects.
Best regards,
Igor
-
October 4th, 2014, 02:56 PM
#11
Re: Calling a function in AfxBeginThread
Originally Posted by Igor Vartanov
All the other APIs dealing with window handles are perfectly thread safe, maybe with a few rare exceptions related to message queue pumping specifics.
well... the "problem" there is that some API functions will send messages even though the call itself doesn't seem like it does.
The most Obvious one of that is Get/SetWindowText()
-
October 5th, 2014, 01:40 AM
#12
Re: Calling a function in AfxBeginThread
The program is working fine right now, it fills the list control without blocking the interface, why is it needed to use send messages instead of controlling the elements from thread ? I've never experienced crashes that's why i'm asking
-
October 5th, 2014, 03:24 AM
#13
Re: Calling a function in AfxBeginThread
Originally Posted by OReubens
well... the "problem" there is that some API functions will send messages even though the call itself doesn't seem like it does.
The most Obvious one of that is Get/SetWindowText()
And? The call you mentioned has no chance to be deadlocked as the called thread is not going to acquire any resource from caller thread during setting window text. So it's what I call perfectly thread safe. Same thing with most of other similar APIs.
Best regards,
Igor
-
October 5th, 2014, 03:56 AM
#14
Re: Calling a function in AfxBeginThread
Originally Posted by eclessiastes;2164105... why is it needed to use [hl
send messages[/hl] instead of controlling the elements from thread ?
Wrong! A worker thread has to post messages to the main UI thread, not to send!
Haven't you read the J.Newcomer's essay about Using Worker Threads?
Victor Nijegorodov
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|