简体   繁体   English

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

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

If there are multiple threads all waiting on the same lock is it possible to have the Main thread have higher priority in acquiring the lock. 如果有多个线程在同一个锁上等待,则主线程可能在获取锁时具有更高的优先级。 Meaning that if worker threads go to the lock statement before the main thread, the main thread would acquire the lock before the other threads that were already waiting on it. 这意味着如果工作线程在主线程之前转到lock语句,主线程将在已经等待它的其他线程之前获取锁。

No, the lock statement maps to System.Threading.Monitor.Enter() ( MSDN ) and there is no overload that accepts a priority parameter. 不, lock语句映射到System.Threading.Monitor.Enter()MSDN ),并且没有接受优先级参数的重载。

The closest thing I can think of is a ReaderWriterLock(Slim) but I would seriously reconsider the design that leads to this request. 我能想到的最接近的是ReaderWriterLock(Slim),但我会认真地重新考虑导致这个请求的设计。 There probably are better ways to achieve what you need. 可能有更好的方法来实现您的需求。

Through a native lock statement, no. 通过本机锁定声明,没有。 Through your own custom locking mechanism, sure, if you're willing to spend the time and effort to develop it. 通过您自己的自定义锁定机制,当然,如果您愿意花时间和精力来开发它。

Here's my draft aa solution. 这是我的草案解决方案。 It may or may not work, and may not be super efficient, but it's at least a starting place: 它可能有效也可能无效,可能效率不高,但它至少是一个起点:

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

Here is another solution. 这是另一种解决方案。 I has a lot of lines, but it is pretty simple. 我有很多行,但很简单。 The function DoSomethingSingle will be called only one thread at a time, and those with the highPriority flag will get preference. 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);
            }
        }
    }

This allows two priority levels. 这允许两个优先级。 Guaranteed that a low priority thread will gain access to the resource only if there are no high priority threads waiting for it. 保证只有在没有高优先级线程等待它时,低优先级线程才能获得对资源的访问权限。

edit: change to interlock incr/dec 编辑:更改为互锁incr / dec

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM