如果有多个线程都在等待同一个锁,是否可以让主线程在获取锁时具有更高的优先级。这意味着如果工作线程lock
在主线程之前执行语句,则主线程将在已经等待它的其他线程之前获得锁。
问问题
3070 次
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 回答