Jeśli istnieje wiele wątków, wszystkie oczekujące na tę samą blokadę, to możliwe, że gwinty główne mają wyższy priorytet w uzyskaniu blokady. Oznacza to, że jeśli wątki robocze przechodzą do instrukcji lock
przed głównym wątkiem, główny wątek uzyskałby blokadę przed innymi wątkami, które już na nim czekały.C# czy można zmienić priorytet uzyskania blokady?
Odpowiedz
Nie, instrukcja lock
mapuje na System.Threading.Monitor.Enter()
(MSDN) i nie ma przeciążenia, które akceptuje parametr priorytetu.
Najbliższą rzeczą, o jakiej mogę myśleć, to ReaderWriterLock (Slim), ale poważnie zastanowiłbym się nad projektem, który prowadzi do tej prośby. Prawdopodobnie istnieją lepsze sposoby osiągnięcia tego, czego potrzebujesz.
Poprzez natywną instrukcję blokady, nie. Dzięki własnemu własnemu mechanizmowi blokowania, na pewno, jeśli chcesz poświęcić czas i wysiłek, aby go rozwinąć.
Oto mój szkic rozwiązania. Może, ale nie musi działać, i może nie być super efektywny, ale jest to co najmniej miejsce początkowe:
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;
}
}
}
Oto inne rozwiązanie. Mam wiele linii, ale jest to całkiem proste. Funkcja DoSomethingSingle
będzie wywoływana tylko jeden wątek na raz, a preferowane będą te z flagą 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);
}
}
}
Umożliwia to dwa poziomy priorytetu. Gwarantuje, że wątek o niskim priorytecie uzyska dostęp do zasobu tylko wtedy, gdy oczekują na niego wątki o wysokim priorytecie.
edit: zmiana blokady INCR/DEC
- 1. Jak zmienić priorytet procesu?
- 2. Czy można ustawić priorytet wątków w Stream.parallel()?
- 3. Czy można zmienić ciąg znaków w C?
- 4. C++ słowniku priorytet
- 5. Jak zmienić priorytet akcji w Wordpress?
- 6. Czy można zmienić obszar alokacji zmiennych automatycznych w C/C++?
- 7. Czy można zmienić kierunek skali?
- 8. Czy możliwe jest zaimplementowanie mapy wolnej od blokady w C++
- 9. C# niższy priorytet wątku w puli wątków
- 10. Czy języki zapytań mają priorytet operatora OR wyższy niż priorytet AND?
- 11. Czy istnieje instrukcja blokady w VB.NET?
- 12. Czy ten wątek użycia blokady jest bezpieczny?
- 13. Jak zmienić priorytet obsługi zdarzenia w Symfony 2
- 14. log4net GenericFailure. Nie można uzyskać blokady pliku
- 15. blokady, która pozwoli wielu czytelników w C#
- 16. Operacje atomowe C++ dla struktur bez blokady
- 17. Czy można zmienić plik application.css na application.css.sass?
- 18. MakeCert - Czy można zmienić rozmiar klucza?
- 19. Czy można zmienić przekierowanie root WSO2?
- 20. Czy można zmienić funkcję repr w pythonie?
- 21. Czy można zmienić metodę wyszukiwania w LINQ?
- 22. TFS - Czy można zmienić nazwę definicji kompilacji?
- 23. Czy można zmienić czcionkę narzędzia ToolStripMenuItem?
- 24. Czy można zmienić program Scala REPL programowo?
- 25. Czy można zmienić dialekt vim regexp?
- 26. Czy można zmienić wyrównanie elementu zastępczego UISearchBar?
- 27. Czy można zmienić nazwę pliku w CodeBlocks?
- 28. Czy można zmienić nazwę tabeli w Firebird?
- 29. Czy można zmienić nazwę maven-with-dependencies?
- 30. Czy można zmienić klasę obiektu Ruby?
tylko ciekaw, czy istnieje jakikolwiek powód, to nie może używać IDisposable? – wwahammy
@wwahammy Nie ma powodu, nie. – Servy