Click to See Complete Forum and Search --> : Newbie encounter with multithreading?


dp_76
September 7th, 2005, 05:37 AM
Hi

I have to convert a single-threaded windows explorer type MFC SDI application into a multi threaded one.

I have gone thru few multithreading articles & has decided to follow the following path:


In the project, there is one user defined class(process.cpp) that does all the processing work.

In this cpp file there are 2 functions that does quite heavy processing. I have decided to implement these 2 functions in

two seperate User Interface threads.

Why User Interface thread: --> bcaz the user at any time, has the facility to stop the processing of these 2 functions.


Also at the time one of these 2 functions are running, the GUI(Tree view,statusbars & message log) is consistently updated.

Since MFC objects are not thread safe i will post message to the main thread to update the GUI.


I think my strategy is correct.

If i m going in the wrong direction plz correct me.

I am waiting for suggestions.


Also i want to ask this:

In the main application class CStApp(derived from CWinApp), there are almost 25 variables which are heavily used throughout

the project.

Can i use these variable safely in the 2 functions which will now be called from the run() of my UI thread


I am waiting for suggestions


Regards. :(

MikeAThon
September 7th, 2005, 01:17 PM
...I have decided to implement these 2 functions in two seperate User Interface threads.

Why User Interface thread: --> bcaz the user at any time, has the facility to stop the processing of these 2 functions.

Although this is fine in this situation, UI threads are not really needed here and you can accomplish your objective with plain worker threads too. The processing of a worker thread can be stopped at any time if the worker periodically checks a value like "BOOL m_bStillOkToContinue" and terminates if it's false. The main GUI thread can allow the user to set the variable to false, and when the worker thread makes its next check it will terminate, thereby accomplishing your objective of allowing termination at any time.

Also at the time one of these 2 functions are running, the GUI(Tree view,statusbars & message log) is consistently updated.

Since MFC objects are not thread safe i will post message to the main thread to update the GUI.

This is good programming and generally correct.

...In the main application class CStApp(derived from CWinApp), there are almost 25 variables which are heavily used throughout the project.

Can i use these variable safely in the 2 functions which will now be called from the run() of my UI thread

Not without significant modification. You need to (1) add a critical section to protect access to these variables, and (2) allow access to the variables only indirectly, through SetValue and GetValue functions.

Preferably, all variables should be protected with a single critical section, to help minimize the chance of thread lock (although thread lock is still something you need to watch for). Here's what you do:

(1) define a critical section member variable for your CStApp class, e.g.,// .. in the StApp.h file
CCriticalSection m_csVariableProtect;

(2) define SetValue and GetValue functions for each variable, and promise yourself that your code will never access any of these variables directly, but rather will always access them indirectly using the SetValue and GetValue functions. Here's a prototype:
// .. in the StApp.cpp file
CStApp::SetValueVarOne( int iNewValue )
{
CSingleLock tLock( &m_csVariableProtect, TRUE );
m_VarOne = iNewValue;
}

int CStApp::GetValueVarOne()
{
CSingleLock tLock( &m_csVariableProtect, TRUE );
return m_VarOne;
}

Good luck,
Mike

cipher1024
September 7th, 2005, 01:47 PM
I think what mikethon says is right u should be using worker threads as far as concurrency control is concerned u can accomplish it using the CSemaphore class refer to MSDN online

MikeAThon
September 7th, 2005, 01:59 PM
I think what mikethon says is right u should be using worker threads as far as concurrency control is concerned u can accomplish it using the CSemaphore class refer to MSDN online
I think that a critical section is a better choice for synchronization in this case, as compared to a semaphore.

Mike

dp_76
September 8th, 2005, 12:52 AM
Hi Mike
Thanx for the clear & precise suggestion.
I now have a very clear idea of how i shud proceed.


Also i want to ask this:

In the worker thread, i decide to post message like this to the main thread:

UINT myfirstworkerthread(LPVOID pParam)
{
---------
---------
--------- //some code goes here.
---------
---------

//Now is the time to post msg to the main thread.

PostMessage(WM_UPDATE_GUI, 0, 0);


if(pApp->bStopWThread)
AfxEndThread(-1);


return 0;
}


Do you think the above code is fine & shud be implemented?

I have also seen the function PostThreadMessage() but not too sure about
it because of the following lines in MSDN:

"When calling the Windows PostThreadMessage function within an MFC application, the MFC message handlers are not called." :confused:

what shud i use: PostMessage() OR PostThreadMessage().

Waiting for suggestions

Best Regards

MikeAThon
September 8th, 2005, 01:31 PM
...Do you think the above code is fine & shud be implemented?

That code looks fine. You might also consider use of the lParam and wParam parameters, perhaps to pass "hints" to your GUI thread about what aspects need an update.

I have also seen the function PostThreadMessage() but not too sure about it because of the following lines in MSDN:

"When calling the Windows PostThreadMessage function within an MFC application, the MFC message handlers are not called."

You are probably referring to KB article Q142415 found at http://support.microsoft.com/default.aspx?scid=kb;en-us;142415. If so, then this issue was resolved a long time ago, with the release of VC++ version 4.1 which correctly implements the ON_THREAD_MESSAGE macro.

However....
what shud i use: PostMessage() OR PostThreadMessage().
Use PostMessage and avoid PostThreadMessage. The reason is complicated, but it involves the very strong possibility that messages posted with PostThreadMessage might be lost, under some very natural real-world situations (such as if your application is displaying a modal dialog, or if the user is dragging the window of your application, at the same time as when the message is posted). This does not happen with PostMessage.

For more information, read http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/postthreadmessage.asp

Mike

dp_76
September 20th, 2005, 03:52 AM
Hi Mike i wanted to rate your post but i m being denied.

It says "You must spread some Reputation around before giving it to MikeAThon again."

Regards :wave:

anand_study
October 8th, 2005, 12:11 AM
To achieve concurrency for object in multithreaded app, usually you can use locking technique. Reading following useful articles will be helpful.

Websites : www.ddj.com and www.cuj.com
You need to register for Free Basic 6-months membership and login to read all of these articles.
Article1 - The Trouble with Locks (C/C++ Users Journal March, 2005)
Article2 - A Fundamental Turn Toward Concurrency in Software (Dr. Dobb's Journal, 30(3), March 2005)

Anand