0

I am trying to understand if my application hangs because of slow I/O, a computationally expensive algorithm, or mutually exclusive access to resources. In that scenario using interfaces and implementing them in classes that may cause in locking, may avoid locking or not.

I understand that Interface is programming structure where we define functions/services that we want to expose to public or other modules as well as avoiding circular dependency.

Kumar Gaurav
  • 899
  • 5
  • 19
  • 35
  • 7
    No, interfaces are completely unrelated to deadlocks (and if you have a deadlock then it is, by definition, because synchronized access to a shared resource not slow I/O). Of course some conditions (slow I/O, CPU intensive algorithms) _may_ cause a deadlock to appear more often. – Adriano Repetti Jan 08 '14 at 09:15
  • You should probably just profile the application (using the visual studio profiler, or a tool such as ANTS profiler) to determine what the application is doing. – Anders Forsgren Jan 08 '14 at 09:16
  • Interfaces and deadlock are orthogonal – Sriram Sakthivel Jan 08 '14 at 09:21
  • 2
    Attach debugger to your application and break execution when it's hanged, exploring thread list and their stacks you can see if they're waiting on a shared resource (for example with a common lock A,B | lock B,A condition). – Adriano Repetti Jan 08 '14 at 09:22

3 Answers3

4

No. Rather the opposite, since an interface hides the implementation you'll have a harder time seeing the lock that causes the problem.

Use the debugger's Debug + Windows + Threads to see what threads are running and which one is executing code that acquired the lock. You can also see the thread ID of the thread that owns the lock, check this answer.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

No, interfaces are completely unrelated to deadlocks. If you have a deadlock then it is, by definition, because synchronized access to a shared resource not slow I/O):

A deadlock is a situation in which two or more competing actions are each waiting for the other to finish, and thus neither ever does.

How to Debug Them?
There can be many causes for a deadlock (of course some conditions - slow I/O, CPU intensive algorithms - may cause a deadlock to appear more often but they're not The Cause).

Most of times it's easy to detect them if you can attach debugger to your application. Pause execution when it's hanged, explore thread list and their stacks you can see if they're waiting on a shared resource.

A very common deadlock scenario is this:

  • Thread 1 acquires lock on resource A.
  • Thread 2 acquires lock on resource B.
  • Thread 1 tries to acquire lock on resource B but it's locked by thread 2 then thread 1 will be suspended (little bit simplified).
  • Thread 2 tries to acquire lock on resource A but it's locked by thread 1 then thread 2 will be suspended.
  • Both threads are suspended then they can't release locks they acquired. If there isn't a timeout then this condition won't be solved (application, or a part of it, may hang).

Another very common scenario:

  • Thread 1 acquires a lock on resource A, (not using, for example, lock statement in C# but directly with Monitor.Enter() or through another synchronization primitive like ReadWriterLockSlim).
  • Execution fails because of an exception. Exception is handled but lock isn't released.
  • First time another thread (or same thread if lock supports reentrancy) will try to use same lock then application will hang (because lock has never been released).

This is a code example (very naive lock mechanism, I know):

object _syncRoot = new object();

void ThreadWorker(object state ) {
    Monitor.Enter(_syncRoot);

    try {
        // Do some operation that may fail

        // Release lock
        Monitor.Exit(_syncRoot);
    }
    catch (Exception e) {
        // Log error
    }
}

Fortunately this is pretty easy to avoid (check this answer to see how lock implements monitor).

try {
    lock (_syncRoot) {
        // Do your job here   
    }
}

In previous scenario same thread won't be hanged if it'll re-access this lock (but other thread will) but if you're using, for example, a read/write lock then it'll hang (or it'll fail if it doesn't support reentrancy, see this question for other details). This kind of failures may be detected if you use a timeout for your locks (of course this is not always possible). When a lock attempt will timeout your application will detect it and take proper actions (if any, it may even simply abort gracefully).

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
1

Interfaces do not changes what codes executes at runtime. Locking is purely a runtime thing. For deadlocks, only the code that actually executes matters. It does not matter how methods are called.

usr
  • 168,620
  • 35
  • 240
  • 369