[英]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.