i want to reset static control's text in a mutiple thread programe
but it doesn't work.....
someone tell me that mfc classes could not be uesd in MT enviorment
so,can someone tell me how to solve this problem??
i am dealing with the dining-philosopher problem thanks!
here is my code....
Take a look at the following FAQ (http://www.codeguru.com/forum/showthread.php?t=312454)...
MikeAThon
November 21st, 2004, 04:22 PM
For something as simple as setting text of a static control, I think that custom messages might be too complex (correct, true, but too complex anyway).
Your code includes a bunch of commented-out lines like pctrwnd->SetWindowText(szT), and I presume this is the basis of your inquiry. Remember that these MFC functions are simple wrappers over the basis SendMessage functions of the API. Unlike the MFC wrappers, it's permissible to use the plain API between threads. However, to avoid the thread-switch that's needed before SendMessage returns, I suggest that you use PostMessage, something likePostMessage( pctrwnd->m_hWnd, WM_SETTEXT, LPARAM(szT), 0L);
Note that since szT will change between the time that you post the message, and the time that the UI thread processes it, there may be some de-synchronization between what the thread is doing and what the UI is displaying.
In addition, and this is important, your main dialog's DiningPhilosopher function is incorrect because it will block/freeze the UI until the threads are complete. Create the threadInfo structures on the heap with new, and eliminate the call to WaitForMultipleObjects. Each thread should create its own local copies of needed variables from threadInfo (like you're already diing now), and then call delete to free its memory. Unless you eliminate the call to WaitForMultipleObjects, your main UI thread will be stuck in the DiningPhilosopher function, and will not be able to update its display, for the reason that while it's stuck in DiningPhilosopher, it will not be able to service its message queue.
Mike
Andreas Masur
November 21st, 2004, 04:44 PM
For something as simple as setting text of a static control, I think that custom messages might be too complex (correct, true, but too complex anyway).
You actually misinterpreted my previous post a little bit...well...maybe, I could have written a little bit more... :rolleyes:
The FAQ was intended to show him how to access GUI elements fro a thread...using messages. Thus, I simply wanted to show him the way of doing it. I did not mean that user-defined messages are necessary in this case.
Sorry for not being clearer...
SSnake
November 23rd, 2004, 12:31 AM
thank you both very much.
I have modified my code as the faq tells.
And i have eliminated the call to WaitForMultipleObjects,and create the threadInfo structures on the heap with new.
But there comes another problem.....
there are five static controls in my dialog,four change their texts while the threads are running,but the fifth control did not change its text and cause an error.
the error messagebox tells that debug assertion failed.
and then i run the programe in the debug model,and it seems the the postmessage instruction cause the problem.
doesn't GetSafeHwnd() returns the same window handle ???
i modified the codes again.I defined five handles ,just like phObjectHandle1,phObjectHandle2....
and i assigned them to the five structs.
but still vc returns an error like what i haved said in the last thread.
MikeAThon
November 23rd, 2004, 08:44 AM
the call to delete should be done by each thread (on its own threadInfo object) after the thread has finished copying the object. Do not call delete from the dialog, or you run the risk that the object gets deleted before the thread has copied important information.
Mike
PS: I also do not understand your logic in assigning and the re-assigning the value of mutexnum (and the value of MutexName). I think you will end up with values that do not correspond between the threrad and the main dialog (e.g., one will count from 1 to 5 whereas the other will count from 0 to 4).
SSnake
November 23rd, 2004, 10:18 AM
to Mike
Do you mean i shoule delete phObjectHandle in the thread function?
what do you mean by "the thread has finished copying the object"?
Does that mean i should define a threadInfo structure in the thread function and copy the variable that passed to the thread function to the newly defined structure and then delete phObjectHandle? But phObjectHandle is only a handle,is it matter to use it in the thread function?Could i delete it at the last of
the thread function?
And,only the fifth static control could not change the text and cause the error messagebox.The other four static controls coule change their texts.
p.s. Because each philosopher could dine only if he have two chopsticks.
So i define five mutex objects represent the five chopsticks.
The variable mutexnum defined in the thread function is used to represent the index of the chopstick. For one philosopher shoule gain the chopstick on the left side and the chopstick on the right side,i defined two handles (leftchopstick,rightchopstick).
SSnake
November 23rd, 2004, 11:48 PM
well i used spy++ to detect the message that postmessage instruction send out.
and i found that the message that should be sent to change the fifth static control's text did not be sent out...........
MikeAThon
November 24th, 2004, 12:48 AM
well i used spy++ to detect the message that postmessage instruction send out.
and i found that the message that should be sent to change the fifth static control's text did not be sent out...........
Well, what message was sent out, and what did you expect that should have been sent out?
...
p.s. Because each philosopher could dine only if he have two chopsticks.
So i define five mutex objects represent the five chopsticks.
The variable mutexnum defined in the thread function is used to represent the index of the chopstick. For one philosopher shoule gain the chopstick on the left side and the chopstick on the right side,i defined two handles (leftchopstick,rightchopstick).
I think I understand the basic idea, but I still think that there's a name mis-match in the mutexName (and mutexNum). In the main thread, the mutexNum ranges from 0 to 4, whereas in the threads the mutexNum ranges from 1 to 5. I think that this difference might explain why all the philosophers work except for the fifth one.
Mike
SSnake
November 24th, 2004, 06:15 AM
when i use spy++ to detect the message,the programme did not cause error messagebox,but it stop running after the the fourth thread send out the WM_UPDATE_CONTROL message(this is message that was defined by myself) to set the fourth static control's text to be "hungry".
Sometimes the fifth thread sent out the message too.but still the programme stop running after this message was sent out.
"In the main thread, the mutexNum ranges from 0 to 4"??
well ,in the main thread,i defined five threadInfo structure,and set their variable pID from 1 to 5 ,and then in the thread function,i set the vaule of mutexNum to be
these pIDs.
here are the codes:
///////////in the main thread
threadInfo thInfo[5];
thInfo[0].pID=1;
thInfo[0].pwnd=phObjectHandle;
thInfo[1].pID=2;
thInfo[1].pwnd=phObjectHandle;
thInfo[2].pID=3;
thInfo[2].pwnd=phObjectHandle;
thInfo[3].pID=4;
thInfo[3].pwnd=phObjectHandle;
thInfo[4].pID=5;
thInfo[4].pwnd=phObjectHandle;
//////////in the thread function
mutexnum=(int)(((threadInfo*)(pParam))->pID);
MikeAThon
November 24th, 2004, 12:31 PM
Please re-read your code. In the thread, the value of mutexNum is actually set to three (and maybe even four) different values, and is not apparently used with consistency to usage in the main dialog's thread.
Mike
SSnake
November 25th, 2004, 04:01 AM
to Mike
first ,thank you very much for helping me.
Please re-read your code. In the thread, the value of mutexNum is actually set to three (and maybe even four) different values, and is not apparently used with consistency to usage in the main dialog's thread.
Mike
at first,the value of mutexnum is set to be the index of the philosopher,that also represent the index of the chopstick that is on the left side of the philosopher
mutexnum=(int)(((threadInfo*)(pParam))->pID);
and then ,the value of mutexnum is set to be the index of the right chopstick
mutexnum=((int)(((threadInfo*)(pParam))->pID)+1)%5;
if(mutexnum==0)
mutexnum=5;
at last ,it is reset to be the index of the philosopher
mutexnum=(int)(((threadInfo*)(pParam))->pID);
and when i call the postmessage function,the fourth parameter
(LPARAM)mutexnum+1003 represent the id of the static control