if there are two threads as producer/consumer is it good idea to have following line to prevent deadlocks. I'm aware of live locks but suppose they do a lot of work before calling this Wait() method:
// member variable
object _syncLock = new object();
void Wait()
{
lock (_syncLock)
{
Monitor.Pulse(_syncLock);
Monitor.Wait(_syncLock);
}
}
Here it's impossible both threads be in waiting state.
This seems overly complicated. Just handle your locking correctly in the first place, and avoid the issue. If you only have two threads, and they are trying to acquire the same, single lock (correctly), you shouldn't have deadlocks. A deadlock means there is something else occurring here.
That being said, if you have the option of using the TPL via .NET 4 (or the Rx Extensions on .NET 3.5), you might want to consider using BlockingCollection<T> instead. It's ideally suited to use in a producer/consumer scenario, and works in a lockless manner.
If your intention is to create a paired variant of the producer-consumer pattern then the sequence is Pulse before Wait for the producer and Wait before Pulse for the consumer. You can reference figure 5 in Joe Duffy's article on this. Howerver, keep in mind that since his implementation performs an unconditional Wait in the Enqueue method a ping-pong like effect will occur between the producer and the consumer. The queue, in his implementation, can only ever have one item per producer. So if that is your intention then this your ticket. Otherwise, you can adapt it as-is and apply some condition1 to the Wait in the Enqueue method to make it behave more like a real FIFO buffer.
However, like Reed, I question why BlockingCollection could not be used. This collection should be very efficient since it uses a lock-free strategy for the Add and Take methods. Of course, like I mentioned above, if you really want the paired variant then this collection will not meet your requirements and you will have to roll your own using Joe Duffy's as a starting point.
1Just remember to use a while loop instead of an if check before applying the wait. Monitor.Wait simply waits for a change in the lock state and nothing more so you have to recheck the wait condition.
Related
Suppose I want to use a non thread-safe class from the .Net Framework (the documentation states that it is not thread-safe). Sometimes I change the value of Property X from one thread, and sometimes from another thread, but I never access it from two threads at the same time. And sometimes I call Method Y from one thread, and sometimes from another thread, but never at the same time.
Is this means that I use the class in a thread-safe way, and the fact that the documentation state that it's not thread-safe
is no longer relevant to my situation?
If the answer is No: Can I do everything related to a specific object in the same thread - i.e, creating it and calling its members always in the same thread (but not the GUI thread)? If so, how do I do that? (If relevant, it's a WPF app).
No, it is not thread safe. As a general rule, you should never write multi threaded code without some kind of synchronization. In your first example, even if you somehow manage to ensure that modifying/reading is never done at the same time, still there is a problem of caching values and instructions reordering.
Just for example, CPU caches values into a register, you update it on one thread, read it from another. If the second one has it cached, it doesn't go to RAM to fetch it and doesn't see the updated value.
Take a look at this great post for more info and problems with writing lock free multi threaded code link. It has a great explanation how CPU, compiler and CLI byte code compiler can reorder instructions.
Suppose I want to use a non thread-safe class from the .Net Framework (the documentation states that it is not thread-safe).
"Thread-safe" has a number of different meanings. Most objects fall into one of three categories:
Thread-affine. These objects can only be accessed from a single thread, never from another thread. Most UI components fall into this category.
Thread-safe. These objects can be accessed from any thread at any time. Most synchronization objects (including concurrent collections) fall into this category.
One-at-a-time. These objects can be accessed from one thread at a time. This is the "default" category, with most .NET types falling into this category.
Sometimes I change the value of Property X from one thread, and sometimes from another thread, but I never access it from two threads at the same time. And sometimes I call Method Y from one thread, and sometimes from another thread, but never at the same time.
As another answerer noted, you have to take into consideration instruction reordering and cached reads. In other words, it's not sufficient to just do these at different times; you'll need to implement proper barriers to ensure it is guaranteed to work correctly.
The easiest way to do this is to protect all access of the object with a lock statement. If all reads, writes, and method calls are all within the same lock, then this would work (assuming the object does have a one-at-a-time kind of threading model and not thread-affine).
Suppose I want to use a non thread-safe class from the .Net Framework (the documentation states that it is not thread-safe). Sometimes I change the value of Property X from one thread, and sometimes from another thread, but I never access it from two threads at the same time. And sometimes I call Method Y from one thread, and sometimes from another thread, but never at the same time.
All Classes are by default non thread safe, except few Collections like Concurrent Collections designed specifically for the thread safety. So for any other class that you may choose and if you access it via multiple threads or in a Non atomic manner, whether read / write then it's imperative to introduce thread safety while changing the state of an object. This only applies to the objects whose state can be modified in a multi-threaded environment but Methods as such are just functional implementation, they are themselves not a state, which can be modified, they just introduce thread safety for maintaining the object state.
Is this means that I use the class in a thread-safe way, and the fact that the documentation state that it's not thread-safe is no longer relevant to my situation? If the answer is No: Can I do everything related to a class in the same thread (but not the GUI thread)? If so, how do I do that? (If relevant, it's a WPF app).
For a Ui application, consider introducing Async-Await for IO based operations, like file read, database read and use TPL for compute bound operations. Benefit of Async-Await is that:
It doesn't block the Ui thread at all, and keeps Ui completely responsive, in fact post await Ui controls can be directly updated with no Cross thread concern, since only one thread is involved
The TPL concurrency too makes compute operations blocking, they summon the threads from the thread Pool and can't be used for the Ui update due to Cross thread concern
And last: there are classes in which one method starts an operation, and another one ends it. For example, using the SpeechRecognitionEngine class you can start a speech recognition session with RecognizeAsync (this method was before the TPL library so it does not return a Task), and then cancel the recognition session with RecognizeAsyncCancel. What if I call RecognizeAsync from one thread and RecognizeAsyncCancel from another one? (It works, but is it "safe"? Will it fail on some conditions which I'm not aware of?)
As you have mentioned the Async method, this might be an older implementation, based on APM, which needs AsyncCallBack to coordinate, something on the lines of BeginXX, EndXX, if that's the case, then nothing much would be required to co-ordinate, as they use AsyncCallBack to execute a callback delegate. In fact as mentioned earlier, there's no extra thread involved here, whether its old version or new Async-Await. Regarding task cancellation, CancellationTokenSource can be used for the Async-Await, a separate cancellation task is not required. Between multiple threads coordination can be done via Auto / Manual ResetEvent.
If the calls mentioned above are synchronous, then use the Task wrapper to return the Task can call them via Async method as follows:
await Task.Run(() => RecognizeAsync())
Though its a sort of Anti-Pattern, but can be useful in making whole call chain Async
Edits (to answer OP questions)
Thanks for your detailed answer, but I didn't understand some of it. At the first point you are saying that "it's imperative to introduce thread safety", but how?
Thread safety is introduced using synchronization constructs like lock, mutex, semaphore, monitor, Interlocked, all of them serve the purpose of saving an object from getting corrupt / race condition. I don't see any steps.
Does the steps I have taken, as described in my post, are enough?
I don't see any thread safety steps in your post, please highlight which steps you are talking about
At the second point I'm asking how to use an object in the same thread all the time (whenever I use it). Async-Await has nothing to do with this, AFAIK.
Async-Await is the only mechanism in concurrency, which since doesn't involved any extra thread beside calling thread, can ensure everything always runs on same thread, since it use the IO completion ports (hardware based concurrency), otherwise if you use Task Parallel library, then there's no way for you to ensure that same / given thread is always use, as that's a very high level abstraction
Check one of my recent detailed answer on threading here, it may help in providing some more detailed aspects
It is not thread-safe, as the technical risk exists, but your policy is designed to cope with the problem and work around the risk. So, if things stand as you described, then you are not having a thread-safe environment, however, you are safe. For now.
I'm trying to move some of my old projects from ThreadPool and standalone Thread to TPL Task, because it supports some very handy features, like continuations with Task.ContinueWith (and from C# 5 with async\await), better cancellation, exception capturing, and so on. I'd love to use them in my project. However I already see potential problems, mostly with synchronization.
I've written some code which shows a Producer / Consumer problem, using a classic stand-alone Thread:
class ThreadSynchronizationTest
{
private int CurrentNumber { get; set; }
private object Synchro { get; set; }
private Queue<int> WaitingNumbers { get; set; }
public void TestSynchronization()
{
Synchro = new object();
WaitingNumbers = new Queue<int>();
var producerThread = new Thread(RunProducer);
var consumerThread = new Thread(RunConsumer);
producerThread.Start();
consumerThread.Start();
producerThread.Join();
consumerThread.Join();
}
private int ProduceNumber()
{
CurrentNumber++;
// Long running method. Sleeping as an example
Thread.Sleep(100);
return CurrentNumber;
}
private void ConsumeNumber(int number)
{
Console.WriteLine(number);
// Long running method. Sleeping as an example
Thread.Sleep(100);
}
private void RunProducer()
{
while (true)
{
int producedNumber = ProduceNumber();
lock (Synchro)
{
WaitingNumbers.Enqueue(producedNumber);
// Notify consumer about a new number
Monitor.Pulse(Synchro);
}
}
}
private void RunConsumer()
{
while (true)
{
int numberToConsume;
lock (Synchro)
{
// Ensure we met out wait condition
while (WaitingNumbers.Count == 0)
{
// Wait for pulse
Monitor.Wait(Synchro);
}
numberToConsume = WaitingNumbers.Dequeue();
}
ConsumeNumber(numberToConsume);
}
}
}
In this example, ProduceNumber generates a sequence of increasing integers, while ConsumeNumber writes them to the Console. If producing runs faster, numbers will be queued for consumption later. If consumption runs faster, the consumer will wait until a number is available. All synchronization is done using Monitor and lock (internally also Monitor).
When trying to 'TPL-ify' similar code, I already see a few issues I'm not sure how to go about. If I replace new Thread().Start() with Task.Run():
TPL Task is an abstraction, which does not even guarantee that the code will run on a separate thread. In my example, if the producer control method runs synchronously, the infinite loop will cause the consumer to never even start. According to MSDN, providing a TaskCreationOptions.LongRunning parameter when running the task should hint the TaskScheduler to run the method appropriately, however I didn't find any way to ensure that it does. Supposedly TPL is smart enough to run tasks the way the programmer intended, but that just seems like a bit of magic to me. And I don't like magic in programming.
If I understand how this works correctly, a TPL Task is not guaranteed to resume on the same thread as it started. If it does, in this case it would try to release a lock it doesn't own while the other thread holds the lock forever, resulting in a deadlock. I remember a while ago Eric Lippert writing that it's the reason why await is not allowed in a lock block. Going back to my example, I'm not even sure how to go about solving this issue.
These are the few issues that crossed my mind, although there may be (probably are) more. How should I go about solving them?
Also, this made me think, is using the classical approach of synchronizing via Monitor, Mutex or Semaphore even the right way to do TPL code? Perhaps I'm missing something that I should be using instead?
Your question pushes the limits of broadness for Stack Overflow. Moving from plain Thread implementations to something based on Task and other TPL features involves a wide variety of considerations. Taken individually, each concern has almost certainly been addressed in a prior Stack Overflow Q&A, and taken in aggregate there are too many considerations to address competently and comprehensively in a single Stack Overflow Q&A.
So, with that said, let's look just at the specific issues you've asked about here.
TPL Task is an abstraction, which does not even guarantee that the code will run on a separate thread. In my example, if the producer control method runs synchronously, the infinite loop will cause the consumer to never even start. According to MSDN, providing a TaskCreationOptions.LongRunning parameter when running the task should hint the TaskScheduler to run the method appropriately, however I didn't find any way to ensure that it does. Supposedly TPL is smart enough to run tasks the way the programmer intended, but that just seems like a bit of magic to me. And I don't like magic in programming.
It is true that the Task object itself does not guarantee asynchronous behavior. For example, an async method which returns a Task object could contain no asynchronous operations at all, and could run for an extended period of time before returning an already-completed Task object.
On the other hand, Task.Run() is guaranteed to operate asynchronously. It is documented as such:
Queues the specified work to run on the ThreadPool and returns a task or Task<TResult> handle for that work
While the Task object itself abstracts the idea of a "future" or "promise" (to use synonymous terms found in programming), the specific implementation is very much tied to the thread pool. When used correctly, you can be assured of asynchronous operation.
If I understand how this works correctly, a TPL Task is not guaranteed to resume on the same thread as it started. If it does, in this case it would try to release a lock it doesn't own while the other thread holds the lock forever, resulting in a deadlock. I remember a while ago Eric Lippert writing that it's the reason why await is not allowed in a lock block. Going back to my example, I'm not even sure how to go about solving this issue.
Only some synchronization objects are thread-specific. For example, Monitor is. But Semaphore is not. Whether this is useful to you or not depends on what you are trying to implement. For example, you can implement the producer/consumer pattern with a long running thread that uses BlockingCollection<T>, without needing to call any explicit synchronization objects at all. If you did want to use TPL techniques, you could use SemaphoreSlim and its WaitAsync() method.
Of course, you could also use the Dataflow API. For some scenarios this would be preferable. For very simple producer/consumer, it would probably be overkill. :)
Also, this made me think, is using the classical approach of synchronizing via Monitor, Mutex or Semaphore even the right way to do TPL code? Perhaps I'm missing something that I should be using instead?
IMHO, this is the crux of the matter. Moving from Thread-based programming to the TPL is not simply a matter of a straight-forward mapping from one construct to another. In some cases, doing so would be inefficient, and in other cases it simply won't work.
Indeed, I would say a key feature of TPL and especially of async/await is that synchronization of threads is much less necessary. The general idea is to perform operations asynchronously, with minimal interaction between threads. Data flows between threads only at well-defined points (i.e. retrieved from the completed Task objects), reducing or even eliminating the need for explicit synchronization.
It's impossible to suggest specific techniques, as how best to implement something will depend on what exactly the goal is. But the short version is to understand that when using TPL, very often it is simply unnecessary to use synchronization primitives such as what you're used to using with the lower-level API. You should strive to develop enough experience with the TPL idioms that you can recognize which ones apply to which programming problems, so that you apply them directly rather than trying to mentally map your old knowledge.
In a way, this is (I think) analogous to learning a new human language. At first, one spends a lot of time mentally translating literally, possibly remapping to adjust to grammar, idioms, etc. But ideally at some point, one internalizes the language and is able to express oneself in that language directly. Personally, I've never gotten to that point when it comes to human languages, but I understand the concept in theory :). And I can tell you firsthand, it works quite well in the context of programming languages.
By the way, if you are interested in seeing how TPL ideas taken to extremes work out, you might like to read through Joe Duffy's recent blog articles on the topic. Indeed, the most recent version of .NET and associated languages have borrowed heavily from concepts developed in the Midori project he's describing.
Tasks in .Net are a hybrid. TPL brought tasks in .Net 4.0, but async-await only came with .Net 4.5.
There's a difference between the original tasks and the truly asynchronous tasks that came with async-await. The first is simply an abstraction of a "unit of work" that runs on some thread, but asynchronous tasks don't need a thread, or run anywhere at all.
The regular tasks (or Delegate Tasks) are queued on some TaskScheduler (usually by Task.Run that uses the ThreadPool) and are executed by the same thread throughout the task's lifetime. There's no problem at all in using a traditional lock here.
The asynchronous tasks (or Promise Tasks) usually don't have code to execute, they just represent an asynchronous operation that will complete in the future. Take Task.Delay(10000) for example. The task is created, and completed after 10 seconds but there's nothing running in the meantime. Here you can still use the traditional lock when appropriate (but not with an await inside the critical section) but you can also lock asynchronously with SemaphoreSlim.WaitAsync (or other async synchronization constructs)
Is using the classical approach of synchronizing via Monitor, Mutex or Semaphore even the right way to do TPL code?
It may be, that depends on what the code actually does and whether it uses TPL (i.e. Tasks) or async-await. However, there are many other tools you can now use like async synchronization constructs (AsyncLock) and async data structures (TPL Dataflow)
I've got an application where there are several threads that provide data, that needs to go through some heavy math. The math part needs a lot of initialization, afterwards it's pretty fast - as such I can't just spawn a thread every time I need to do the calculation, nor should every source thread have its own solver (there can be a LOT of such threads, beyond a certain point the memory requirements are obscene, and the overhead gets in the way or processing power).
I would like to use a following model: The data gathering and using threads would call to a single object, through one thread-safe interface function, like
public OutData DoMath(InData data) {...}
that would take care of the rest. This would involve finding a free worker thread (or waiting and blocking till one is available) passing by some means the data in a thread safe manner to one of the free worker threads, waiting (blocking) for it to do its job and gathering the result and returning it.
The worker thread(s) would then go into some sleep/blocked state, until a new input item would appear on its interface (or a command to clean up and die).
I know how to do this by means of various convoluted locks, queues and waits in a very horrible nasty way. I'm guessing there's a better, more elegant way.
My questions are:
Is this a good architecture for this?
Are there commonly used elegant means of doing this?
The target framework is .NET 4.5 or higher.
Thank you,
David
The math part needs a lot of initialization, afterwards it's pretty fast - as such I can't just spawn a thread every time I need to do the calculation, nor should every source thread have its own solver (there can be a LOT of such threads, beyond a certain point the memory requirements are obscene, and the overhead gets in the way or processing power).
Sounds like a pool of lazy-initialized items. You can use a basic BlockingCollection for this, but I recommend overriding the default queue-like behavior with a stack-like behavior to avoid initializing contexts you may not ever need.
I'll call the expensive-to-initialize type MathContext:
private static readonly BlockingColleciton<Lazy<MathContext>> Pool;
static Constructor()
{
Pool = new BlockingCollection<Lazy<MathContext>>(new ConcurrentStack<Lazy<MathContext>>());
for (int i = 0; i != 100; ++i) // or whatever you want your upper limit to be
Pool.Add(new Lazy<MathContext>());
}
This would involve finding a free worker thread (or waiting and blocking till one is available)
Actually, there's no point in using a worker thread here. Since your interface is synchronous, the calling thread can just do the work itself.
OutData DoMath(InData data)
{
// First, take a context from the pool.
var lazyContext = Pool.Take();
try
{
// Initialize the context if necessary.
var context = lazyContext.Value;
return ... // Do the actual work.
}
finally
{
// Ensure the context is returned to the pool.
Pool.Add(lazyContext);
}
}
I also think you should check out the TPL Dataflow library. It would require a bit of code restructuring, but it sounds like it may be a good fit for your problem domain.
Investigate Task Parallel Library. It has a set of methods for creating and managing threads. And such classes as ReaderWriterLock, ManualResetEvent
and their derivatives may help in synchronizing threads
Don't use locks. This problem sounds nice for a proper nearly lock free approach.
I think what you need to look into is the BlockingCollection. This class is a powerful collection for multiple consumers and producers. If you think about using it with Parallel.ForEach you may want to look into writing your own Partitioner to get some more performance out of it. Parallel contains a couple of very nice methods if you only need a couple of threads for a relatively short time. That sounds like something you need to do. There are also overloads that provide initialization and finalization methods for each spawned thread along with passing thread local variables from one stage of the function to the next. That may really help you.
The general tips apply here of cause too. Try to split up your application in as may small parts as possible. That usually clears things up nicely and the ways how to do things become clearer.
All in all from what you told about the problem at hand I do not think that you need a lot of blocking synchronization. The BlockingCollection is only blocking the consumer threads until new data is ready to be consumed. And the producer if you limit the size...
I can't think of anything beyond that out of the top of my head. This is a very general question and without some specific issues it is hard to help beyond that.
I still hope that helps.
You've pretty much described a thread pool - fortunately, there's quite a few simple APIs you can use for that. The simplest is probably
await Task.Run(() => DoMath(inData));
or just call Task.Run(() => DoMath(inData)).GetAwaiter().GetResult() if you don't mind blocking the requesting thread.
Instead of starting a whole new thread, it will simply borrow a thread from the .NET thread pool for the computation, and then return the result. Since you're doing almost pure CPU work, the thread pool will have only as much threads as you really need (that is, about the same (or double) amount as the number of CPU cores you have).
Using the await based version is a bit trickier - you need to ensure your whole call chain returns Tasks - but it has a major advantage in avoiding the need to keep the calling thread alive while you wait for the results to be done. And even better, if you make sure the original thread is also a thread-pool thread, you don't even need the Task.Run - the threads will be balanced automatically. Since you're only doing synchronous work anyway, this turns your whole problem into simply avoiding any manual new Thread, and using Task.Run(...) instead.
First, create a pool of N such "math service objects" that are heavy. Then, guard usage of that pool with a new SemaphoreSlim(N, N). Accessing those objects is then as easy as:
SemaphoreSlim sem = ...;
//...
await sem.WaitAsync();
var obj = TakeFromPool();
DoWork(obj);
Return(obj);
sem.Release();
You can vary this pattern in many ways. The core of it is the pool plus a semaphore that can be used to wait if the pool is empty at the time.
I was wondering on the Monitor Class.
As far as i know all waiting threads are not FIFO.
The first one that aquires the lock is not allways the first on in the waiting queue.
Is this correct?
Is there some way to ensure the FIFO condition?
Regards
If you are referring to a built-in way, then no. Repeatedly calling TryEnter in a loop is by definition not fair and unfortunately neither is the simple Monitor.Enter. Technically a thread could wait forever without getting the lock.
If you want absolute fairness you will need to implement it yourself using a queue to keep track of arrival order.
Is there some way to ensure the FIFO condition?
In a word: no!
I wrote a short article about this: Is the Ready Queue FIFO?
Look at this question, I think it will very useful for you - Does lock() guarantee acquired in order requested?
especially this quote:
Because monitors use kernel objects internally, they exhibit the same
roughly-FIFO behavior that the OS synchronization mechanisms also
exhibit (described in the previous chapter). Monitors are unfair, so
if another thread tries to acquire the lock before an awakened waiting
thread tries to acquire the lock, the sneaky thread is permitted to
acquire a lock.
I have a Queue<T> field that is accessed by various threads. Enequeue() is called from multiple threads many times per second, while there is a single thread that performs the Dequeue() and Count operations.
I havent been thinking much about this until now, since I played it "safe" and used lock on a static object before any operations with this queue. While there currently aren't any performance issue, I would like to get rid of the locks if they are redundant. My questions are:
since I never iterate through the queue, are locks really needed in this situation? I mean, will the program crash when it happens that one thread enqueues and the second thread dequeues elements at exactly the same time?
should I perhaps use Queue.Synchronized() to get a wrapper, and if so: will that impact performance compared to the original queue?
1: yes they are necessary; both enqueue and dequeue mutate state; a standard queue is not thread safe
2: ConcurrentQueue<T> would work nicely; personally I use a version I wrote here on SO, Creating a blocking Queue<T> in .NET? - it makes it easy to throttle the size of the queue, and do efficient dequeues without looping
Note; with your current implementation the lock-object should only be static if the queue is static (that isn't clear in the question, though) - otherwise all your similar queues may be sharing a lock