|
i have a application based on tray icon
in that tray we used popup menu it contains minimise,maximize ;
when i click the maximize buton system menus r not shown like FILE,EDIT ..
can u help me
thanks
k.guru moorthy
|
|
|
|
|
I cannot understand what you said.
|
|
|
|
|
Hello everyone,
In the MSDN volatile sample,
http://msdn2.microsoft.com/en-us/library/12a04hfd(VS.80).aspx
I do not understand what is the purpose of the sample. I have tried to remove the keyword volatile, and the result is the same.
Any ideas?
thanks in advance,
George
|
|
|
|
|
Did you try in the release build?
« Superman »
|
|
|
|
|
Sure, I tried. Same result. Any ideas what is the purpose of the MSDN sample?
regards,
George
|
|
|
|
|
The qualifier volatile is to tell the compiler that the variable may be accessed/changed by any source, and the value of this variable should not be assumed by the compiler for optimization.
To see the effect of volatile , follow the below code, and have VC++ generate an ASM listing file, and compile in Release mode. You will see the difference!!
int v = 5;
int volatile m = 3;
int i;
for(i = 0; i < 10; i++) {
if(v == 5) { break; }
}
for(i = 0; i < 10; i++) {
if(m == 3) { break; }
}
Maxwell Chen
|
|
|
|
|
Cool, Maxwell!
Here is the generated assembly code. Could you show a more practical sample or describe what is the purpose of MSDN sample please? Thanks.
1311006 add byte ptr [eax],al
int i;
for(i = 0; i < 10; i++)
{
if(v == 5)
{
break;
}
}
for(i = 0; i < 10; i++)
01311008 xor eax,eax
0131100A lea ebx,[ebx]
{
if(m == 3)
01311010 mov ecx,dword ptr [esp]
01311013 cmp ecx,ecx
01311015 je main+1Dh (131101Dh)
01311017 inc eax
01311018 cmp eax,0Ah
0131101B jl main+10h (1311010h)
{
break;
}
}
}
regards,
George
|
|
|
|
|
The example in MSDN is interesting! (My computer at work can not paste text in CP, but the one at home can. So I can copy and paste. )
Please read my comments in the code for details.
The result:
Critical Data = 1
Success
volatile bool Sentinel = true;
int CriticalData = 0;
unsigned ThreadFunc1( void* pArguments ) {
while (Sentinel) {
Sleep(0);
}
cout << "Critical Data = " << CriticalData << endl;
return 0;
}
unsigned ThreadFunc2( void* pArguments ) {
Sleep(2000);
CriticalData++;
Sentinel = false;
return 0;
}
int main() {
HANDLE hThread1, hThread2;
DWORD retCode;
hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc1,
NULL, 0, NULL);
hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc2,
NULL, 0, NULL);
if (hThread1 == NULL || hThread2 == NULL) {
cout << "CreateThread failed." << endl;
return 1;
}
retCode = WaitForSingleObject(hThread1,3000);
CloseHandle(hThread1);
CloseHandle(hThread2);
if (retCode == WAIT_OBJECT_0 && CriticalData == 1 )
cout << "Success" << endl;
else
cout << "Failure" << endl;
}
Maxwell Chen
|
|
|
|
|
Thanks Maxwell,
This is the code which makes me confused.
while (Sentinel)
{
Sleep(0);
}
I think when thread1 enters into the while loop, the value of Sentinel is true and it should invokes Sleep(0). Sleep(0) will wait until there is a signal. But in the program no other parties send thread1 a signal, and I think thread1 will wait forever to cause deadlock.
The only reason why there is no deadlock is when thread1 checks variable Sentinel, it happens to be false changed by thread2.
Anything wrong with my previous analysis? Please feel free to correct me.
regards,
George
|
|
|
|
|
Anything wrong with my previous analysis? Please feel free to correct me.
Yes, you're wrong in the following assumption:
George_George wrote: Sleep(0) will wait until there is a signal.
because MSDN http://msdn2.microsoft.com/en-us/library/ms686298.aspx[^] states:
Parameters
dwMilliseconds
The minimum time interval for which execution is to be suspended, in milliseconds.
A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.
i.e. Sleeps(0) , in absence of signals, doesn't wait forever.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
You are correct. I think the behavior of thread1 is to continue to check the value of Sentinel again and again until it is false, right?
regards,
George
|
|
|
|
|
You hit the target, George.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
Now I strongly suspect whether compiler will generate any wrong code -- functional wrong code. In MSDN sample, variable Sentinel is used to act as a shared variable between thread1 and thread2. Compiler should guarantee that both threads can read/write the correct value of Sentinel.
It seems that volatile will make wrong optimization to prevent thread1 from reading the most recent correct value set by thread2? I think it will bring high risks to careless developers, who does not know about volatile and forget to put it ahead of the variable, which will result in the wrong optimization of compiler.
What is your perspective on such optimization?
regards,
George
|
|
|
|
|
No:
(1) thread safe code is up to the programmer.
(2) Optimizations usually undergo some hypothesis, if such hypothesis are broken then code functionality is broken. It is a price to pay to code speed.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
Then I am confused what is the original purpose of the MSDN sample? It advise people to put volatile keyword to all shared variables between multiple threads -- or else function may be broken?
In my past experience, I never use volatile to all threads' shared variables.
regards,
George
|
|
|
|
|
George_George wrote:
Then I am confused what is the original purpose of the MSDN sample? It advise people to put volatile keyword to all shared variables between multiple threads -- or else function may be broken?
That what an extreme sample. The shared variable was used as part of sinchronyzation mechanism (a spinlock) and some optimizations were turned on.
Usually we protect shared variables using some (OS provided) synchronization API, we don't do the opposite.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
I just want to confirm two things,
1. In your experience, when do you use volatile?
2. If we share data between threads and we are already using synchronization approach like mutex, do we need to add additional volatile keyword?
regards,
George
|
|
|
|
|
George_George wrote: 1. In your experience, when do you use volatile?
I never used it. (but I didn't write a lot of multithreaded code).
George_George wrote: If we share data between threads and we are already using synchronization approach like mutex, do we need to add additional volatile keyword?
IMHO no.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
I assume it is not much useful keyword and can be omitted.
regards,
George
|
|
|
|
|
Every keyword is useful. However, having a rather specialised pourpuse, you usually don't see programs with a lot of volatile s inside.
George_George wrote: and can be omitted.
You may omit it only whenever you don't need it (see, for instance, JudyL_FL
reply http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=2372474[^]
)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Yes, CPallini.
I agree it is needed. But currently I only see two cases which need this keyword,
1. Some hardware related, to let compiler read data from real memory other than from register;
2. Multi-threaded environment, I think volatile is only needed when we do not use other techniques, like critical section or mutex. If we use other techniques, volatile is not needed.
How do you think of my understanding?
regards,
George
|
|
|
|
|
In my opinion (I already said I'm not an expert about), your understanding is good.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
Thanks CPallini,
I personally prefer to use critical section or mutex, which has more control of concurrency behavior compared with volatile. Volatile only has very limited function in a multi-threaded environment to share data.
regards,
George
|
|
|
|
|
George_George wrote: 1. In your experience, when do you use volatile?
2. If we share data between threads and we are already using synchronization approach like mutex, do we need to add additional volatile keyword?
I don't use volatile in real-world code.
I started coding C/C++ in 1998. Only in the first year when I'd read volatile keyword, I tested it in exercise code. Well, at that time I did not know what debug/release builds were. I did not see the difference. Later on in 1999, I learned some more things, so I tried to use it. At that time, the threading design of mine was so poor. Yes, volatile was used in my early code, for once or twice. Finally I realized that with proper design for synchronisation mechanism of threading, volatile is not necessary.
Maxwell Chen
|
|
|
|
|
Maxwell Chen wrote: I don't use volatile in real-world code
I never did either when I was just writing for windows. An event serves the purpose of using a "flag" variable between threads. However, now that I'm writing cross-platform code, I find myself using "volatile flag" variables quite often for my multi-threaded stuff. The ease of use of the Windows event is not found on other platforms. I find it simpler to use the volatile keyword to prevent the compiler from optimizing away my variable rather than trying to find the best-for-each-platform way of implementing a simple signalling event between threads.
Judy
|
|
|
|
|