|
-
April 13th, 2012, 04:35 PM
#1
Mutex never works
Why does this code not deadlock when entering the same critical section 2 times in a row?
Code:
#define _WIN32_WINNT 0x0403
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
CRITICAL_SECTION Mutex;
int _tmain(int argc, _TCHAR* argv[]) {
// Initialize the mutex
if (!InitializeCriticalSectionAndSpinCount(&Mutex,0x00000001)) {
wprintf(L"Could not initialize the mutex.");
}
EnterCriticalSection(&Mutex);
EnterCriticalSection(&Mutex);
wprintf(L"This should be impossible to reach because of deadlock.");
LeaveCriticalSection(&Mutex);
LeaveCriticalSection(&Mutex);
// Release the mutex
DeleteCriticalSection(&Mutex);
return 0;
}
-
April 13th, 2012, 04:54 PM
#2
Re: Mutex never works
Because multiple calls from the same thread doesn't block. It's all described here http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Always read the documentation!
-
April 13th, 2012, 05:11 PM
#3
Re: Mutex never works
Multiple threads does not work either when I call my C++ component from Visual Basic 6. If Visual Basic make all calls from the same thread then this type of mutex is useless.
Last edited by Dawoodoz; April 13th, 2012 at 05:16 PM.
-
April 13th, 2012, 05:17 PM
#4
Re: Mutex never works
Well, all I can say is that you probably do or get something wrong. You don't expect yourself to be the very first person that find a bug in EnterCriticalSection do you?
-
April 13th, 2012, 05:21 PM
#5
Re: Mutex never works
ok, thanks for your time anyway.
-
April 14th, 2012, 09:25 PM
#6
Re: Mutex never works
 Originally Posted by Dawoodoz
Multiple threads does not work either when I call my C++ component from Visual Basic 6. If Visual Basic make all calls from the same thread then this type of mutex is useless.
So, what is the problem here? Multiple threads not working, or VB making calls in the same thread, or in your case this type of mutex being useless?
Multiple threads work fine with critical sections, guaranteed. Nothing can I say about thread model of VB, but it's quite easy to figure out. And in case this what you tried seems useless for you, you always can go with some other solution.
In the latter case you need to explain your design as well as show your real code but not this fake one.
Best regards,
Igor
-
April 15th, 2012, 08:01 AM
#7
Re: Mutex never works
My real code is around 100000 lines and not easy to show.
If I understand the threading model correct then Visual Basic is going around the mutex because each call is made to a different copy of the engine in appartment threading.
I need to make sure that only one call at once is made to the engine no matter what framework is calling the component.
Raising an exception when a call is blocked would be okay because I just want to protect beginners from damaging the operative system.
-
April 15th, 2012, 11:07 AM
#8
Re: Mutex never works
 Originally Posted by Dawoodoz
My real code is around 100000 lines and not easy to show.
If I understand the threading model correct then Visual Basic is going around the mutex because each call is made to a different copy of the engine in appartment threading.
What's confusing you is that you called your critical section "mutex". Why not create a mutex using CreateMutex?
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
As you can see there is a difference between a mutex and a critical section.
From the link above:
Note that critical section objects provide synchronization similar to that provided by mutex objects, except that critical section objects can be used only by the threads of a single process.
So from what you're saying, you are using the incorrect synchronization object. You should have been using an actual mutex object, one created with CreateMutex, not a critical section.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; April 15th, 2012 at 11:10 AM.
-
April 15th, 2012, 11:22 AM
#9
-
April 16th, 2012, 09:11 PM
#10
Re: Mutex never works
As synchroization objects, both critical sections and mutexes will behave similarly, if the calling thread already owns the synchronization object. To wait on a mutex, the calling thread calls WaitForSingleObject (or WaitForMultipleObject). If the calling thread already owns the mutex, then the call returns immediately with result code WAIT_OBJECT_0
See the documentation for ReleaseMutex at http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
A thread can specify a mutex that it already owns in a call to one of the wait functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex one time for each time that it obtained ownership (either through CreateMutex or a wait function).
To the OP: Why do you need to "block" a second call to your function. It's not possible for a single thread to call the same function more than once at the same time. Other effects might arise within the context of a single thread (such as re-entrancy issues or deliberately recursive functions), but since these are all executed in the context of a single thread, there are always simple alternatives for dealing with the issue (e.g., set a flag in thread-local memory).
Mike
-
April 17th, 2012, 06:17 AM
#11
Re: Mutex never works
When an application make multiple calls at once using a callback or delay, the engine will crash.
With appartment threading, global variables for flags do not work between different simultaneous calls because they are working on different copies of the memory.
Last edited by Dawoodoz; April 17th, 2012 at 06:24 AM.
Reason: Typo
-
April 17th, 2012, 08:46 AM
#12
Re: Mutex never works
 Originally Posted by Dawoodoz
When an application make multiple calls at once using a callback or delay, the engine will crash.
Which should be read: bad server implementation.
With appartment threading, global variables for flags do not work between different simultaneous calls because they are working on different copies of the memory.
Sure, because global variables are supposed to do only in case of singleton.
Best regards,
Igor
-
April 17th, 2012, 02:15 PM
#13
Re: Mutex never works
 Originally Posted by Dawoodoz
When an application make multiple calls at once using a callback or delay, the engine will crash.
What is the relationship of this observation to your original question on threading and mutexes/critical sections? There doesn't seem to be any relation at all. What do you mean by "crash", which is a completely unhelpful description? So far, this problem sounds terribly ordinary, as if there is poorly synchronized access to memory across threads.
 Originally Posted by Dawoodoz
With appartment threading, global variables for flags do not work between different simultaneous calls because they are working on different copies of the memory.
If a variable is truly "global", then there cannot be "different copies of it in memory".
I tend to think that there is an underlying bad architecture, or there is a poor understanding and/or usage of an otherwise good architecture. You mentioned that there are 100000 lines of code, but if this is an achitectural issue, then it should be straightforward to show the basics in a sample of far fewer lines of code. Please do so, or do a better job at explaining what you want.
And let's look for a moment back at the code in your original post:
 Originally Posted by Dawoodoz
Code:
#define _WIN32_WINNT 0x0403
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
CRITICAL_SECTION Mutex;
int _tmain(int argc, _TCHAR* argv[]) {
// Initialize the mutex
if (!InitializeCriticalSectionAndSpinCount(&Mutex,0x00000001)) {
wprintf(L"Could not initialize the mutex.");
}
EnterCriticalSection(&Mutex); // #1
EnterCriticalSection(&Mutex); // #2
wprintf(L"This should be impossible to reach because of deadlock."); // #3
LeaveCriticalSection(&Mutex);
LeaveCriticalSection(&Mutex);
// Release the mutex
DeleteCriticalSection(&Mutex);
return 0;
}
According to your post, it should not be possible to reach #3 because the attempt to EnterCriticalSection at #2 should be blocked by the previous acquisition of the critical section at #1.
If this is correct, then there would be deadlock without possibility of escaping. Think about it: the thread that called EnterCriticalSection at #1 owns the critical section and is the only thread that can release it. But if the thread were blocked by the call to EnterCriticalSection at #2, then the thread becomes irretrievably deadlocked, because (under your scenario) it's the only one that could release the critical section but it can't do anything -- muchless release a critical section -- because it's blocked at #2.
That of course is not the way that critical sections (or other synchronization primitives like mutexes) work, as explained in the documentation.
Mike
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
|