9

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

4

3 回答 3

8

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

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

于 2012-10-17T20:43:54.513 回答
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;
        }
    }
}
于 2012-10-17T21:17:01.353 回答
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

于 2016-07-01T15:51:04.623 回答