簡體   English   中英

C#是否可以改變獲取鎖的優先級?

[英]C# is it possible to change priority of acquiring a lock?

如果有多個線程在同一個鎖上等待,則主線程可能在獲取鎖時具有更高的優先級。 這意味着如果工作線程在主線程之前轉到lock語句,主線程將在已經等待它的其他線程之前獲取鎖。

不, lock語句映射到System.Threading.Monitor.Enter()MSDN ),並且沒有接受優先級參數的重載。

我能想到的最接近的是ReaderWriterLock(Slim),但我會認真地重新考慮導致這個請求的設計。 可能有更好的方法來實現您的需求。

通過本機鎖定聲明,沒有。 通過您自己的自定義鎖定機制,當然,如果您願意花時間和精力來開發它。

這是我的草案解決方案。 它可能有效也可能無效,可能效率不高,但它至少是一個起點:

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;
        }
    }
}

這是另一種解決方案。 我有很多行,但很簡單。 DoSomethingSingle函數一次只調用一個線程,而具有highPriority標志的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM