C#是否可以改变获取锁的优先级?

时间:2012-10-17 20:39:24

标签: c# multithreading

如果有多个线程在同一个锁上等待,则可以让主线程获得锁定具有更高的优先级。这意味着如果工作线程在主线程之前转到lock语句,主线程将在已经等待它的其他线程之前获取锁。

3 个答案:

答案 0 :(得分:7)

不,lock语句映射到System.Threading.Monitor.Enter()MSDN),并且没有接受优先级参数的重载。

我能想到的最接近的是ReaderWriterLock(Slim),但我会认真重新考虑导致此请求的设计。可能有更好的方法来实现您的需求。

答案 1 :(得分:2)

通过本机锁定语句,没有。通过您自己的自定义锁定机制,当然,如果您愿意花时间和精力来开发它。

这是我的草案解决方案。它可能有效也可能无效,可能效率不高,但它至少是一个起点:

public class Lock
{
    bool locked = false;

    private object key = new object();
    SortedDictionary<int, Queue<ManualResetEvent>> notifiers =
        new SortedDictionary<int, Queue<ManualResetEvent>>();

    ManualResetEvent specialNotifier = null;

    public void Lock()
    {
        lock (key)
        {
            if (locked)
            {
                ManualResetEvent notifier = new ManualResetEvent(false);

                int priority = getPriorityForThread();

                Queue<ManualResetEvent> queue = notifiers[priority];
                if (queue == null)
                {
                    queue = new Queue<ManualResetEvent>();
                    notifiers[priority] = queue;
                }

                queue.Enqueue(notifier);

                notifier.WaitOne();
            }
            else
            {
                locked = true;
            }
        }
    }

    private static int getPriorityForThread()
    {
        return 0;
    }

    public void Release()
    {
        lock (key)
        {
            foreach (var queue in notifiers.Values)
            {
                if (queue.Any())
                {
                    var notifier = queue.Dequeue();
                    notifier.Set();
                    return;
                }
            }
            locked = false;
        }
    }
}

答案 2 :(得分:1)

这是另一种解决方案。我有很多行,但很简单。函数DoSomethingSingle一次只能被调用一个线程,而highPriority标志的那个将获得优先权。

    static int numWaiting = 0;
    static object single = new object();

    ResultType DoSomething(string[] argList, bool highPriority = false)
    {
        try
        {
            if (highPriority)
            {
                Interlocked.Increment(ref numWaiting);
            }

            for (;;)
            {
                lock (single)
                {
                    if (highPriority || numWaiting == 0)
                    {
                        return DoSomethingSingle(argList);
                    }
                }
                // Sleep gives other threads a chance to enter the lock
                Thread.Sleep(0);
            }
        }
        finally
        {
            if (highPriority)
            {
                Interlocked.Decrement(ref numWaiting);
            }
        }
    }

这允许两个优先级。保证只有在没有高优先级线程等待它时,低优先级线程才能访问资源。

编辑:更改为互锁incr / dec