【问题标题】:Deadlocks in GraphEngineGraphEngine 中的死锁
【发布时间】:2017-03-05 10:23:47
【问题描述】:

在使用 GraphEngine 一段时间后,我经常发现自己在对 GraphEngine 执行一些操作时遇到了死锁线程。嵌套调用绝对不在菜单上。但是现在我遇到了一些奇怪的事情:

foreach(long cellID ...)
{
    byte[] buffer;

    // the next line will block on the 54th call...
    Global.LocalStorage.LoadCell(cellID, out buffer);
}

怀疑我使用了一个不存在的 cellID

if(Global.LocalStorage.Contains(cellID))
{ ... }

但现在这个调用无限期地阻塞了。

这是一个错误吗?或

在什么情况下调用会阻塞?

欢呼, 安德烈亚斯。

【问题讨论】:

    标签: graphengine


    【解决方案1】:

    @Andreas Hassmann,我遇到了类似的问题,所以我猜你的问题可能是由 foreach-loop 中的... 引起的。

    我使用了像 Global.LocalStorage.xxxCell_Accessor_Selector().Select(c => c.CellID.Value) 这样的迭代器。在这种情况下,存储的锁还没有被释放,导致Global.LocalStorage.LoadCell()获取锁时死锁。

    如果您的问题与我的完全相同,解决方案是将.ToList() 应用于迭代器。

    这是我的代码来重现您的问题。

    TSL:

    cell struct MyCell 
    {
        int A; 
    }
    

    代码:

    for (int i = 0; i < 100; i++)
    {
        MyCell mc = new MyCell(i);
        Global.LocalStorage.SaveMyCell(i, mc);
    }
    
    var ids = Global.LocalStorage.MyCell_Accessor_Selector().Select(c => c.CellID.Value);
    
    Console.WriteLine("1 start.");
    foreach (long cellID in ids.ToList())
    {
        byte[] buffer;
        Global.LocalStorage.LoadCell(cellID, out buffer);
        Console.WriteLine(cellID);
    }
    Console.WriteLine("1 done.");
    
    Console.WriteLine("2 start.");
    foreach (long cellID in ids) 
    {
        byte[] buffer;
        Global.LocalStorage.LoadCell(cellID, out buffer);
        Console.WriteLine(cellID);
    }
    Console.WriteLine("2 done.");
    

    【讨论】:

    • 谢谢,L.H.!我必须为简化我的问题而道歉。我的 CellID 来自对不同 CellType 的迭代,并且 LoadCell 在第 54 次调用时被阻塞,而不是在第一次调用时阻塞。这就是为什么我怀疑有违规行为。但是,是的,我也用 ToList() 绕过了它。但这将使 Trinity 中的任何聪明的迭代器实现毫无用处,如果它们存在的话。
    • @AndreasHassmann 我知道你想要什么,我找到了另一个解决方案:如果我们不更新迭代器中的任何数据,我们可以将 Trinity 存储设置为“只读”模式,即将启用任意操作而无需担心锁。我的解决方案是首先初始化存储并将存储保存到磁盘,然后在加载和迭代存储之前放置这些代码:TrinityConfig.CurrentRunningMode = RunningMode.Embedded; TrinityConfig.ReadOnly = true; Global.LocalStorage.LoadStorage();
    • 再次感谢 L.H. 这听起来好像无法在运行时切换,对吧?我将不得不重新连接到数据库。你是梁河吗?我想和建造它的人一起谈论 Trinity,而不是在这里的公共空间乱扔垃圾......
    • 是的,你是对的,如果我们想在加载数据后使用'readonly'模式,我们需要重新连接它。是的,我是梁河。我在 Trinity 上有很多练习,我想在这里尽可能地分享我的经验。如需更多讨论,您也可以在此处发布:github.com/Microsoft/GraphEngine/issues
    猜你喜欢
    • 1970-01-01
    • 2014-08-26
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多