I am facing the problem, that I have an C# (.NET) object shared among some threads. A thread might replace the object with another one. The threads are waken up from a TCP/IP connection using the Asynchronous framework.
Sequence:
Threads (waiting for connection) -> Asynchronous Callback -> Do something thread-safe ->
Access the shared object -> Do something thread-safe.
1. Solution Mutex:
Object sharedObject = new Object();
Mutex objectMutex = new Mutex();
void threadCallback()
{
Object newObject = new Object();
// some processing
objectMutex.lock();
// do exchange sharedObject with newObject if needed
// very little processing here
objectMutex.unlock();
// some processing
}
2. Solution Interlock
Object sharedObject = new Object();
int usingSharedObject = 0;
void threadCallback()
{
Object newObject = new Object();
// some processing
// poll until we lock
while(1 == Interlocked.Exchange(ref usingSharedObject , 1))
{
// do exchange sharedObject with newObject if needed
// very little processing here
Interlocked.Exchange(ref usingSharedObject , 0); // free lock
}
// some processing
}
What is faster and scales up better?
I expect the second solution to be faster as long as there are not to many threads polling at the same time. The second solution might even sleep a random time so that polling does not eat up any processing time. The first solution looks cleaner to me if I really do need to process a lot of TCP/IP connections. Since I do very little processing in the locked section regarding the TCP/IP processing, will there be any scale-up-issues?
How about the object creation at the beginning of the threadCallback() function.
In my C++ background I always used memory-pools in such a situation, since I must use safe .NET is there a fast way to create new Objects or does the .NET platform perform well in this field.
Best regards,
Friedrich
Looking at the second example the way that it works, it appears that if the lock wasn’t acquired you are going to exit, skipping the important part of your code.
The Mutex approach is much easier to understand and I have not had any performance issues with it.