C # Threading - lock - how to check for locks

Im using a latching object in my application with multiple threads.

How can I check how many times other threads tried to work with a locked object, or how much time did I spend trying to update a locked object?

My code is based on the best answer here:

Mutliple threads update array

Edit: code copied:

float[] bestResult; object sync = new Object(); lock (sync) { if (bestResult[0] > calculatedData[0]) { bestResult = calculatedData; } } 
+4
source share
4 answers

The System.Diagnostics.Stopwatch class can help you:

 float[] bestResult; object sync = new Object(); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); lock (sync) { sw.Stop(); if (bestResult[0] > calculatedData[0]) { bestResult = calculatedData; } } Console.WriteLine("Time spent waiting: " + sw.Elapsed); 
+5
source

The question asked was how to determine the number of lock attempts or the amount of time wasted due to a lock conflict.

The answer to this question is to use a profiler, such as the one that comes with Visual Studio Premium Edition. Other .NET profiles may exist.

It is incorrect to add a counting / timing code in each lock statement, as it will have its own lock problems. Therefore, in the absence of a profiler, you must perform a static analysis. It's not so scary. Nested loops are a big key.

The lock conflict becomes the largest in server design. Fortunately, the user's session state is private to the session. If you use APM (asynchronous programming model - callbacks), then provided that you do not call socket.BeginRead until the end of your handler, from the point of view of the session, state operations are effectively single-threaded. Therefore, in these conditions, blocking is necessary only for setting and breaking a session. During the session, this is completely unnecessary.

That's why I prefer APM to newer and more fashionable ways to handle parallel execution.

+1
source

A good tool to start a blocking investigation is the Concurrency Visualizer , as described here . Don't be afraid of this blog article since 2010. The same principles still apply in newer versions of Concurrency Visualizer for a newer version of Visual Studio.

+1
source

I'm not a thread expert, but in order for the number of times other threads tried to work on an object, you probably have to implement a more primitive version of the lock mechanism than Lock . I gave him a snapshot with a tightly looped Monitor.TryEnter and comments are welcome.

Of course, the implementation of something like this in itself can easily lead to an increase in blocking time and more blocks in order to get the scores you need, and on the basis of the fact that this implementation is certainly not identical to how the lock works inside . Anyway, I wasted time, so I'm going to post it.

  class Program { static object lockObj = new object(); static void Main(string[] args) { System.Threading.Thread t = new System.Threading.Thread(proc); System.Threading.Thread t2 = new System.Threading.Thread(proc); t.Start(); t2.Start(); t.Join(); t2.Join(); Console.WriteLine("Total locked up time = " + (LockWithCount.TotalWaitTicks / 10000) + "ms"); Console.WriteLine("Total blocks = " + LockWithCount.TotalBlocks); Console.ReadLine(); } static void proc() { for (int x = 0; x < 100; x++) { using (new LockWithCount(lockObj)) { System.Threading.Thread.Sleep(10); } } } } 

The above shows how to use LockWithCount by replacing an existing Lock() {} with using(new LockWithCount(x)) {}

  class LockWithCount : IDisposable { static System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); object lockObj; public static long TotalWaitTicks = 0; public static long TotalBlocks = 0; static LockWithCount() { watch.Start(); } public LockWithCount(object obj) { lockObj = obj; long startTicks = watch.ElapsedTicks; if (!System.Threading.Monitor.TryEnter(lockObj)) { System.Threading.Interlocked.Increment(ref TotalBlocks); System.Threading.Monitor.Enter(lockObj); System.Threading.Interlocked.Add(ref TotalWaitTicks, watch.ElapsedTicks - startTicks); } } public void Dispose() { System.Threading.Monitor.Exit(lockObj); } } 
0
source

Source: https://habr.com/ru/post/1441665/


All Articles