|
Max++ wrote: How to Hide windows
Install Lynux
led mike
|
|
|
|
|
Hi,
I have a multithreaded program in which I use the following class object "ClassLock" the synchronize accesses :
<br />
#ifndef CLASSLOCK_H<br />
#define CLASSLOCK_H<br />
<br />
extern CRITICAL_SECTION g_ClassLock;<br />
<br />
class ClassLock<br />
{<br />
public:<br />
static void InitCriticalSection();<br />
static void DelCriticalSection();<br />
inline ClassLock() { EnterCriticalSection( &g_ClassLock ); }<br />
inline ~ClassLock() { LeaveCriticalSection( &g_ClassLock ); }<br />
};<br />
<br />
#endif
I protect a function call by instantiating a ClassLock object at the beginning of the function :
<br />
void MyFunc()<br />
{<br />
ClassLock l;<br />
...<br />
}<br />
But sometimes, don't know why, an exception is thrown. How can I deal with this ?
My idea would be the following modification, but I don't know if it's safe and smart :
<br />
inline ClassLock() { while(!TryEnterCriticalSection( &g_ClassLock )) { } }<br />
Any other ideas ? Thanks
|
|
|
|
|
Tnarol wrote: How can I deal with this ?
Find out what the exception is.
Is the purpose and use model of that class supposed to be evident? I don't get it.
led mike
|
|
|
|
|
led mike wrote: Is the purpose and use model of that class supposed to be evident? I don't get it.
Yes,
First at the beginning of your app you call InitCriticalSection() which is in fact InitializeCriticalSection() on a global g_ClassLock variable
Then inside a function when you instantiate a ClassLock object it calls the constructor which locks the g_ClassLock variable using EnterCriticalSection( &g_ClassLock )
When the function return, the ClassLock object goes out of scope, so the destructor is called automatically and it does LeaveCriticalSection( &g_ClassLock )
Therefore the function has the g_ClassLock synchronization token for the duration of its' execution.
Then at the end of the program DelCriticalSection must be called...and it does DeleteCriticalSection( &g_ClassLock ).
|
|
|
|
|
Tnarol wrote: on a global g_ClassLock variable
I don't understand what problem a "global" critical section solves, you want to synchronize everything in the process?
led mike
|
|
|
|
|
It's just that a global variable is a simple kind of synchronization resource that can be seen and shared by several threads in a program.
I could have this variable static in the class, but there are some strange things happening with static variables members of a class, if you use them very early in the program they are sometimes not yet created and it makes you crash. I don't have a logical explanation for this but that's my experience.
|
|
|
|
|
Tnarol wrote: It's just that a global variable is a simple kind of synchronization resource that can be seen and shared by several threads in a program.
I'm sorry but that does not explain anything. A Critical Section is used to synchronize access to data or a section of code, this implies "context" associated with the CS. Have one as "global" elimintates all context.
Tnarol wrote: they are sometimes not yet created
"Created"? static variable addresses are known at load time, therefore any code that uses them has a good address.
Anyway, global or static, I still don't see how that solves anything in regards to using a CS.
led mike
|
|
|
|
|
void MyFunc()<br />
{<br />
ClassLock l;<br />
...<br />
}<br />
You're probably getting an exception because you are entering a critical section
that hasn't been initialized yet.
You also don't want to create a new critical section every time you enter the function
otherwise it will never block.
Try this:
class CMyCriticalSection
{
private:
CRITICAL_SECTION CritSec;
protected:
public:
CMyCriticalSection() {::InitializeCriticalSection(&CritSec);}
virtual ~CMyCriticalSection() {::DeleteCriticalSection(&CritSec);}
void Enter() {::EnterCriticalSection(&CritSec);}
void Leave() {::LeaveCriticalSection(&CritSec);}
};
CMyCriticalSection MyFuncCritSec;
void MyFunc()
{
MyFuncCritSec.Enter();
... (do thread protected stuff)
MyFuncCritSec.Leave();
}
|
|
|
|
|
Thanks, it works fine so far...but the exception occurs very rarely so time will tell.
The problem with this kind of class is that you have to leave critical section explicitly so if you have functions with many return points you must copy the "Leave()" everywhere. Anyway I'm quite confident in this implementation.
|
|
|
|
|
>>The problem with this kind of class is that you have to leave critical section explicitly so if
>>you have functions with many return points you must copy the "Leave()" everywhere.
Cool. I guess I prefer it that way personally I can't recall ever needing to block an entire function.
Anyway I suspect the exception is unrelated to the critical section. But if it only rarely
happens I guess it's ok?
Best of luck,
Mark
|
|
|
|
|
You need two SEPARATE objects.
The first object constructor initializes the critical section, and its destructor deletes the critical section.
It has a member function Lock() and Unlock()
The second class, its constructor Enters the critical section of first object, by calling its Lock function. The destructor of this class calls the Unlock() of the first class.
That way, you don't have to worry about calling Unlock() explicitly from your code.
You also don't have to use a 'global' class from your common code, you use instances of the second class.
If you don't want to block out the entire scope of a function, then use the local scoping operators around the second class and the code like so
{
SecondClass MyLocker;
... code
}
and it will release when closing brace is met.
This is also handy when there is an exception, your critical section is not permanently locked and lost by the unwinding of the exception.
Any sufficiently gross incompetence is nearly indistinguishable from malice.
|
|
|
|
|
Hi all, i'm researching accessing data on a hard drive through using absolute addresses in C/C++. Somthing similar to "peek", and "poke", in
DOS-C. I Dont think its possible using visual studio.net, but someone may know somthing useful. Thanks.
p.s. This is my first question in my first forum, so go easy on me.
Craig
|
|
|
|
|
I think what you are after is CreateFile("\\\\.\\PHYSICALDRIVE0", ...) and ReadFile() .
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Thanks for your prompt reply. What you wrote looks interesting i'll check it out. Thanks again.
Craig
|
|
|
|
|
Take care with that kind of I/O. You could easily fubar a filesystem that way...
--
-= Proudly Made on Earth =-
|
|
|
|
|
In addition to the response from DavidCrow, you must read a number of full sectors in the ReadFile function. Else, ReadFile will fail on you.
A HD sector is normally 512 bytes. The actual sector size can be retrieved with a GetDriveGeometry call.
Alcohol. The cause of, and the solution to, all of life's problems - Homer Simpson
|
|
|
|
|
How to exchange boolean data of Edit Control of a dialog using DDX_....?
|
|
|
|
|
Just like you would any other type:
void AFXAPI DDX_Text( CDataExchange* pDX, int nIDC, int& value );
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Thanks David
But if I try to exchange data between an IDC control and a structure member that is defined as boolean - The compiler poses an error.
What I'm doing right now is to store the value of this struct member (boolean)in an int, exchange the data with int and store this int back in struct member (boolean)- Any better way to do this - ?
|
|
|
|
|
Sonia Horra wrote: Any better way to do this - ?
Not without seeing the actual code.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
You can always write your own custom DDX_ routine. They are not sacrosanct, after all.
Just use the one that does ints as a template and copy the code to your program.
Then modify it to accept the BOOL and do necessary conversions.
Any sufficiently gross incompetence is nearly indistinguishable from malice.
|
|
|
|
|
Is that any way that call CMainFrame's function
from my CDocument class?
Best Regards.
MJM.
|
|
|
|
|
What's wrong with AfxGetMainWnd() ?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Do u mean i use AfxGetMainWnd()
& then use PostMessage to handling that with
CMainFrame class?
|
|
|
|
|
You indicated that you wanted to "call CMainFrame's function from my CDocument class." AfxGetMainWnd() is used to get a pointer to the frame window object. With that, you can call whatever function you need.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|