Interlocked的使用是否正确?

时间:2013-09-24 23:16:49

标签: c# multithreading atomic multicore lockless

我有一个节点树T,N.T表示我正在监视的程序所做的所有内存分配和解除分配的记录。 GUI检查'count'和'bytes'

public class Node
{
    private Dictionary<int, Node> Children = new Dictionary<int, Node>();
    private int count; // Total allocs for all _leaves_ below
    private int bytes; // Total bytes allocated for all _leaves_ below

    protected void Instantiate( StackTrace stackTrace, int index ) { ... }
    protected void Increment( StackTrace stackTrace, int size, int index ) { ... }
    protected void Decrement( StackTrace stackTrace, int size, int index ) { ... }
}

public class Root : Node
{
    private void UpdateTree( StackTrace[] stackTraces ) { ... }
}

我的监控线程将向我的树管理器提交一批堆栈跟踪,我的树管理器(如果堆栈被标记为分配)通过并在树上为堆栈跟踪中的每个方法创建一个节点(如果它还没有存在),一直到system32.dll。这很正常。

完成后,我正在尝试并行更新树(不工作):

private void UpdateTree( StackTrace[] stackTraces )
{
    ForEach(stackTrace in stackTraces)
    {
        if (HasntBeenInstantiated(stackTrace))
            Instantiate(stackTrace, 0);
    }

    Parallel.ForEach (allocs, alloc =>
    {
        if (alloc is AllocationEvent)
            T.Increment(alloc.stack, alloc.size, 0);
        else if (alloc is DeallocationEvent)
            T.Decrement(alloc.stack, alloc.size, 0);
    });
}

private void Instantiate( Stack stack, int size, int index )
{
    if (++index < stack.Length)
        GetOrAddNewChild(stack[index]).Instantiate(stack, index);
}

private void Increment( Stack stack, int size, int index )
{
    Interlocked.Increment(ref count);
    Interlocked.Add(ref bytes, size);

    if (++index < stack.Length)
        GetChild(stack[index]).Increment(stack, index);
}

private void Decrement( Stack stack, int size, int index )
{
    Interlocked.Decrement(ref count);
    Interlocked.Add(ref bytes, -size);

    if (++index < stack.Length)
        GetChild(stack[index]).Decrement(stack, index);
}

在每个批处理中,我保证为除了释放之外的任何叶节点都有更多的分配事件。但不知何故,在处理批处理后,我有时会在某些节点上有负数和/或负字节。 以上内容是否错误?

备注:

我正在避免使用锁和互斥锁,因为更新是无滞后的。只要所有数据都正确输入,每个批次结束时的数字应该是正确的。

修改

原来输入数据存在错误。

0 个答案:

没有答案