The environment:
3 web services 2 in the same pool 1 in a different application pool.
They all have the same code trying to access something that is not thread safe say a file that they write to.
I try and lock this code the same way for each web service. I'm not sure if the lock keyword is doing what I want.
One lock I try is this in each web service:
string stringValue
lock (stringValue)
The other lock I try is:
lock (typeof(MyWebServiceClass))
Will these locks prevent any simultaneous writes to the file while it is in use? In this case there are multiple clients hitting each of these web services.
You need a named Mutex to lock on across application pools /processes:
The C# lock keyword is syntactic sugar for Monitor.Enter(), Monitor.Exit() method calls in a try/finally block. Monitor is a light weight (fully managed) synchronization primitive for in-process locking.
A Mutex on the other hand can be either local or global (across processes on the same machine) - global mutexes, also called named mutexes, are visible throughout the operating system, and can be used to synchronize threads in multiple application domains or processes. Also see MSDN.
I think you need to use a Mutex to lock between AppDomains.
Also, for what its worth, avoid locking on a type. That can often result in deadlocks if code elsewhere tries to lock after the first lock has been obtained. It's best to lock on an object whose only purpose is to act as a lock.
For example:
object padlock;
lock(padlock)
{
// work here
}
Related
I have a component registered in Castle Windsor as a singleton. This object is being used in many other places within my application which is multithreaded.
Is it possible that the two objects will invoke the same method from that singleton at the same time or 'calling it' will be blocked until the previous object will get result?
Thanks
You can call a Singleton object method from different threads at the same time and they would not be blocked if there is no locking/ synchronization code. The threads would not wait for others to process the result and would execute the method as they would execute methods on separate objects.
This is due to the fact that each thread has a separate stack and have different sets of local variables. The rest of the method just describes the process as to what needs to be done with the data which is held the variables/fields.
What you might want to take care of is if the methods on the Singleton object access any static methods or fields/variables. In that case you might need to work on synchronization part of it. You would need to ensure multi-threaded access to shared resources for the execution of the method to be reliable.
To be able to synchronize, you might need to use lock statement or other forms of thread synchronization techniques.
You might want to refer to this article from Wikipedia which provides information on C# thread local storage as well.
You can call the same method or different methods on one object simultaneously from different threads. In the specific methods you'll need to know when sensitive variables are being accessed (mostly when member-variables are changing their values) and will need to implement locking on your own, in order to solve lost updates and other anomalies.
You can lock a part of a code with the lock-statement and here an article on how Thread-Synchronization works in .Net.
The normal version of Singleton may not be thread safe, you could see different implementation of thread safe singleton here.
http://tutorials.csharp-online.net/Singleton_design_pattern:_Thread-safe_Singleton
I am using TvdbLib in a program. This library can use a cache for loading TV series quicker. To further improve the speed of the program, I do all my loading of TV series on separate threads. When two threads run simultaneously and try to read/write from the cache simultaneously, I will get the following error:
The process cannot access the file
'C:\BinaryCache\79349\series_79349.ser' because it is being used by
another process.
Does anyone know how to avoid this and still have the program running smoothly?
CacheProvider is not built for being used in multi-threaded scenarios... either use it in one thread only or lock on every access via a shared object or supply every thread with its own CacheProvider and its own distinct _root directory (in the constructor).
You can use the lock statement to ensure only one thread is accessing the cache at the same time:
http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.71).aspx
From the error I assume that TvdbLib does not support multiple concurrent threads accessing the same cache. As it is an open source project, you could get the source code and implement your own protection around the cache access, e.g., using the lock statement. Of course, you could lock within your own code before it calls TvdbLib, but because this will be a higher level, the lock will be maintained for longer and you may not get the fine-grained concurrency that you want.
I learned about semaphores from an earlier question I had today, and I stll am scratching my head here. There seems to be no discussion about scope beyond global and local, where global is defined as the entire operating system.
If I have an application made from several assemblies, and each assembly has several classes, and each class has a private static semaphore object, with different "queue" lengths, if I start queuing different tasks up in my application thread pool in different places, how does that work? How do the threads behave around each other? All the examples I see include one or two classes in one assembly, and I'm not getting a clear picture on how this works.
I use thread pooling all over my app. It parallelizes data (sending customized emails to various people, generating customized reports en masse, collecting data from various web services, etc) while leaving my interface responsive, which is a wonderful thing.
One of my web service sources limits me to five concurrent connections, and I could not figure out how to limit the web requests to 5 active threads while still allowing the rest of the application to utilize other threads as necessary. So, I turned to SO, and asked how to do it. The proposed answer was use Semaphores.
Until that point, I did not know a thing about semaphores, so I researched it. It does indeed seem to limit the number of threads executing a specific method, but it does not make sense how this communicates properly with the thread pool manager. If I implemented a semaphore on my web request functionality, and I get a backlog of threads waiting to perform web service calls, how does the thread pool know (can it know?) to issue more threads for other processes? The scope of the semaphore is private; it shouldn't see the object.
Further, is that what the semaphore is supposed to do? Can I likewise limit other groups of tasks, by having them share a common semaphore? Is this a gross bastardization of the intent of a semaphore, or exactly what it's meant to do. There's so much information out there on it, but in simplified, abstract form, and I couldn't find an article describing when and how it is appropriate to use these things.
So how does a private static semaphore communicate with the thread pool so the thread pool knows whether or not to spawn another worker thread? Does it? Will I be creating more problems than solutions by doing this? What sort of behavior can I expect my thread pool to exhibit with a backlog of web requests? Will it spawn new threads for the web requests until it's "full", reducing the thread availability for other methods? Can I make it not do that?
The scope constraints, (if you can call them that!), are because the semaphores are OS kernel synchronization primitives that can be used, (unnamed), for inter-thread comms or, (named), or inter-process, (inter-assembly) comms. The language cannot restrict the scope of the named variant.
There is a huge pile of information on semaphores in general on Google. For .NET-wapped ones, MSDN.
Inter-process signalling and communication via. named semaphores is certainly possible in general. How you might do it in the managed environment is another matter. In unmanaged code, it usually involves other comms elements, like shared memory areas and/or memory-mapped files. You should probably not go there.
Be careful about trying to constrain thread pools in different assemblies by making the tasks signa/wait on named semaphores. By all means try it, if you think it may solve some problem with your app, but there is at least the possibility that the pool thread counts, running pool threads, pool threads blocked on semaphores, pool threads blocked inside tasks on IO etc. may become unstable.
You seem to be assuming that the only solution is to partition the builtin .NET thread pool. How about using separate custom thread pools for your task groups? See this link for Jon Skeet's sample code.
What is the difference between lock and Mutex? Why can't they be used interchangeably?
A lock is specific to the AppDomain, while Mutex to the Operating System allowing you to perform inter-process locking and synchronization (IPC).
lock is a compiler keyword, not an actual class or object. It's a wrapper around the functionality of the Monitor class and is designed to make the Monitor easier to work with for the common case.
The Monitor (and the lock keyword) are, as Darin said, restricted to the AppDomain. Primarily because a reference to a memory address (in the form of an instantiated object) is required to manage the "lock" and maintain the identity of the Monitor
The Mutex, on the other hand, is a .Net wrapper around an operating system construct, and can be used for system-wide synchronization, using string data (instead of a pointer to data) as its identifier. Two mutexes that reference two strings in two completely different memory addresses, but having the same data, will actually utilize the same operating-system mutex.
A Mutex can be either local to a process or system-wide. MSDN:
Mutexes are of two types: local mutexes, which are unnamed, and named system mutexes. A local mutex exists only within your process.
Furthermore, one should take special care - detailed on the same page as well - when using a system-wide mutex on a system with Terminal Services.
One of the differences between Mutex and lock is that Mutex utilizes a kernel-level construct, so synchronization will always require at least a user space-kernel space transition.
lock - that is really a shortcut to the Monitor class, on the other hand tries to avoid allocating kernel resources and transitioning to kernel code (and is thus leaner & faster - if one has to find a WinAPI construct that it resembles, it would be CriticalSection).
The other difference is what others point out: a named Mutex can be used across processes.
Unless one has special needs or requires synchronization across processes, it is just better to stick to lock (aka Monitor)˛
There are several other "minor" differences, like how abandonment is handled, etc.
The same can be said about ReaderWriterLock and ReaderWriterLockSlim in 3.5, Semaphore and the new SemaphoreSlim in .NET 4.0 etc.
It is true that the latter xxSlim classes cannot be used as a system-wide sync primitives, but they were never meant to - they were "only" meant to be faster and more resource friendly.
I use a Mutex to check see if I already have a copy of the application running on the same machine.
bool firstInstance;
Mutex mutex = new Mutex(false, #"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);
if (!firstInstance)
{
//another copy of this application running
}
else
{
//run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);
A lot has been said already, but to make it simple, here's my take.
lock -> Simple to use, wrapper on monitor, locks across threads in an AppDomain.
unnamed mutex -> similar to lock except locking scope is more and it's across AppDomain in a process.
Named mutex -> locking scope is even more than unnamed mutex and it's across process in an operating system.
So now options are there, you need to choose the one fits best in your case.
Mutex is a cross process and there will be a classic example of not running more than one instance of an application.
2nd example is say you are having a file and you don't want different process to access the same file , you can implement a Mutex but remember one thing Mutex is a operating system wide and cannot used between two remote process.
Lock is a simplest way to protect section of your code and it is appdomain specific , you can replace lock with Moniters if you want more controlled synchronization.
Few more minor differences which were not mentioned in the answers:
In the case of using locks, you can be sure that the lock will be released when an exception happens inside the lock's block.
That's because the lock uses monitors under the hood and is implemented this way:
object __lockObj = x;
bool __lockWasTaken = false;
try
{
System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
// Your code...
}
finally
{
if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}
Thus, in any case, the lock is released, and you don't need to release it manually (like you'd do for the mutexes).
For Locks, you usually use a private object to lock (and should use).
This is done for many reasons. (More info: see this answer and official documentation).
So, in case of locks, you can't (accidentally gain) access to the locked object from the outside and cause some damage.
But in case of Mutex, you can, as it's common to have a Mutex which is marked public and used from anywhere.
The Lock and Monitors are basically used to provide thread safety for threads that are generated by the application itself i.e. Internal Threads. On the other hand, Mutex ensures thread safety for threads that are generated by the external applications i.e. External Threads. Using Mutex, only one external thread can access our application code at any given point in time.
read this
Maybe the question sounds silly, but I don't understand 'something about threads and locking and I would like to get a confirmation (here's why I ask).
So, if I have 10 servers and 10 request in the same time come to each server, that's 100 request across the farm. Without locking, thats 100 request to the database.
If I do something like this:
private static readonly object myLockHolder = new object();
if (Cache[key] == null)
{
lock(myLockHolder)
{
if (Cache[key] == null)
{
Cache[key] = LengthyDatabaseCall();
}
}
}
How many database requests will I do? 10? 100? Or as much as I have threads?
You have a hierarchy of objects:
You have servers (10)
On each server you have processes (probably only 1 - your service/app pool)
In each process you have threads (probably many)
Your code will only prohibit threads within the same process on the same server access to modify the Cache object simultaneously. You can create locks across processes and even across servers, but the cost increases a lot as you move up the hierarchy.
Using the lock statement does not actually lock any threads. However, if one thread is executing code inside the lock (that is in the block of code following the lock statement) any other thread that wants to take the lock and execute the same code has to wait until the first thread holding the lock leaves the block of code and releases the lock.
The C# lock statement uses a Windows critical section which a lightweight locking mechanism. If you want to lock across processes you can use a mutex instead. To lock across servers you can use a database or a shared file.
As dkackman has pointed out .NET has the concept of an AppDomain that is a kind of lightweight process. You can have multiple AppDomains per process. The C# lock statement only locks a resource within a single AppDomain, and a proper description of the hierarchy would include the AppDomain below the process and above the threads. However, quite often you only have a single AppDomain in a process making the distinction somewhat irrelevant.
The C# lock statement locks on a particular instance of an object (the object you created with new object()). Objects are (in most cases) not shared across AppDomains, thus if you are having 10 servers, 10 threads can run concurrently access your database with that piece of code.
Lock is not blocking threads.
It is locking some instance of an object. And each thread which tries to access it is blocked.
So in your case each thread which will try to access myLockHolder will be locked and not all the threads.
In other words we can say that Lock statement is syntactic sugar for using Critical Section.
Like you can see in MSDN :
lock(expression) statement block
where:
expression Specifies the object that you want to lock on. expression must
be a reference type. Typically,
expression will either be this, if you
want to protect an instance variable,
or typeof(class), if you want to
protect a static variable (or if the
critical section occurs in a static
method in the given class).
statement block The statements of the critical section.
lock will block all threads in that application from accessing the myLockHolder object.
So if you have 10 instances of the application running you'll get 10 requests to the server while the object is locked on each. The moment you exit the lock statement, the next request will process in that application, but as long as Cache[key] is not null, it won't access the database..
The number of actual requests you get depends on what happens here:
if (Cache[key] == null)
{
Cache[key] = LengthyDatabaseCall();
}
If LengthyDatabaseCall(); fails, the next request will try and access the database server and retrieve the information as well, so really your best case scenario is that there will only be 10 requests to the server.
Only the threads that need access to your shared variable at the moment another thread is using it will go into a wait state.
how many that is at any give time is hard to determine.
Your DB will get 10 requests, with odds being good that requests 2-10 run much faster than request 1.