c# - 僵局澄清?

标签 c# .net multithreading deadlock

也许对“死锁”还有其他解释,但据我所知:

reference

A deadlock happens when two threads each wait for a resource held by the other, so neither can proceed.

但是我在这里看到了几个答案,它们声称长时间的等待(不互相等待)也是一个死锁:

<强> Example #1

namespace ConsoleApplication7
{
    public class Program
    {
        public static void Main(string[] args)
        {
            LockableClass lockable = new LockableClass();
            new Thread(new ParameterizedThreadStart(BackgroundMethod)).Start(lockable);
            Thread.Sleep(500);
            Console.Out.WriteLine("calling Reset");
            lockable.Reset();
        }

        private static void BackgroundMethod(Object lockable)
        {
            lock (lockable)
            {
                Console.Out.WriteLine("background thread got lock now");
                Thread.Sleep(Timeout.Infinite);
            }
        }
    }

    public class LockableClass
    {
        public Int32 Value1 { get; set; }
        public Int32 Value2 { get; set; }

        public void Reset()
        {
            Console.Out.WriteLine("attempting to lock on object");
            lock (this)
            {
                Console.Out.WriteLine("main thread got lock now");
                Value1 = 0;
                Value2 = 0;
            }
        }
    }

}

Pardon me but all I see here is a pure lock that hasn't been released. it is not a situation both threads waiting for another. The Thread here does NOT wait for the main thread to finish.

<小时/>

<强> Another example #2

class ILockMySelf
{
    void doThat()
    {
        lock(this){ ... }
    }
}

class WeveGotAProblem
{
    ILockMySelf anObjectIShouldntUseToLock;

    void doThis()
    {
        lock(anObjectIShouldntUseToLock)
        {
            // Following line should run in a separate thread
            // for the deadlock to happen
            anObjectIShouldntUseToLock.doThat();
        }
    }
}

这里也一样。运行 doThis 的线程不会等待将运行 doThat

的“单独线程”

问题:

  • 这里涉及死锁吗?

最佳答案

我同意 David Hope 的观点,死锁的定义很广泛,适用于线程之外的场景。但是,第二个示例不是死锁,因为它不存在导致线程“停止”的情况。

要更正第二个示例,请启动一个新线程强制线程 1 等待线程 2。然后,您可以创建死锁:

//Deadlock
public class Program
{
    public static void Main(string[] args)
    {
        WeveGotAProblem p = new WeveGotAProblem();
        p.doThis();//gain a lock on this thread                        
    }        
}

class ILockMySelf
{
    public void doThat()
    {
        //Thread2 waits on Thread1 to release "this"
        lock (this)
        {
            Console.WriteLine("that");
        }
    }
}

class WeveGotAProblem
{
    ILockMySelf anObjectIShouldntUseToLock = new ILockMySelf();

    public void doThis()
    {
        lock (anObjectIShouldntUseToLock)
        {
            Task task = Task.Factory.StartNew(new Action(() => anObjectIShouldntUseToLock.doThat()));
            Task.WaitAll(task);//Thread1 waits on Thread2 to return.  This is important
        }
    }
}

这里我们有两个或多个相互竞争的 Action ,每个 Action 都等待对方完成。

  • 线程 1 正在等待线程 2 返回。
  • 线程 2 正在等待线程 1 释放其所需的资源,然后才能返回。

第一个示例(尽管是人为的......为什么让线程永远休眠......?)可能会因类似的原因导致死锁。

EG

  • Thread1 等待 Thread.Sleep() 返回(它永远不会)
  • 线程2等待线程1释放lockable上的锁(它永远不会)

事实上,操作是线程,每个线程都在等待不同的结果,这只是实现细节。

关于c# - 僵局澄清?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15032297/

相关文章:

c# - 读取xml文档并更新所有字段c#

c# - 尝试用另一种语言解密时 AES 解密错误

C# 从代码隐藏 (Sitecore) 在页脚中添加外部脚本

Java:wait()、notify() 和嵌套同步块(synchronized block)

c# - 如何让对象支持反序列化?

c# - 对内存位置的无效访问 - 管理到非托管代码

c# - MVC3/C# - 无效的转换异常 - 指定的转换无效

c# - WCF 服务关闭

java - while 循环阻塞其他线程

python - 无法退出异步 Web.py Web 服务器