Я пытаюсь написать окончательный метод "Выход", чтобы дать текущее срез времени другим потокам. До сих пор я обнаружил, что существует несколько способов сделать поток доступным для выделенного временного фрагмента. Я просто хочу убедиться, что я правильно их интерпретирую, так как документация не очень ясна. Итак, из того, что я прочитал в stackoverflow, MSDN и различных блогах, существуют следующие варианты, которые имеют разные преимущества/недостатки:
SwitchToThread
[win32]/ Thread.Yield
[.NET 4 Beta 1]: возвращает любой поток на одном процессоре
- Преимущество: примерно в два раза быстрее, чем
Thread.Sleep(0)
- Недостаток: дает только потоки на одном процессоре
Thread.Sleep(0)
: дает любой поток с одинаковым или более высоким приоритетом на любом процессоре
- Преимущество: быстрее, чем
Thread.Sleep(1)
- Недостаток: дает только потоки того же или более высокого приоритета
Thread.Sleep(1)
: выдает любой поток на любом процессоре
- Преимущество: дает любой поток на любой процессор
- Недостаток: самый медленный вариант
(
Thread.Sleep(1)
будет обычно приостановите поток примерно на 15 мс, еслиtimeBeginPeriod
/timeEndPeriod
[win32] не используются)
Как насчет Thread.SpinWait
? Может ли это использоваться для получения временного среза нити? Если нет, для чего он используется?
Я кое-что еще пропустил или неправильно интерпретировал. Я был бы признателен, если бы вы могли исправить/добавить к моему пониманию.
Вот как выглядит метод Yield:
public static class Thread
{
[DllImport("kernel32.dll")]
static extern bool SwitchToThread();
[DllImport("winmm.dll")]
internal static extern uint timeBeginPeriod(uint period);
[DllImport("winmm.dll")]
internal static extern uint timeEndPeriod(uint period);
/// <summary> yields time slice of current thread to specified target threads </summary>
public static void YieldTo(ThreadYieldTarget threadYieldTarget)
{
switch (threadYieldTarget) {
case ThreadYieldTarget.None:
break;
case ThreadYieldTarget.AnyThreadOnAnyProcessor:
timeBeginPeriod(1); //reduce sleep to actually 1ms instead of system time slice with is around 15ms
System.Threading.Thread.Sleep(1);
timeEndPeriod(1); //undo
break;
case ThreadYieldTarget.SameOrHigherPriorityThreadOnAnyProcessor:
System.Threading.Thread.Sleep(0);
break;
case ThreadYieldTarget.AnyThreadOnSameProcessor:
SwitchToThread();
break;
default: throw new ArgumentOutOfRangeException("threadYieldTarget");
}
}
}
public enum ThreadYieldTarget
{
/// <summary> Operation system will decide when to interrupt the thread </summary>
None,
/// <summary> Yield time slice to any other thread on any processor </summary>
AnyThreadOnAnyProcessor,
/// <summary> Yield time slice to other thread of same or higher piority on any processor </summary>
SameOrHigherPriorityThreadOnAnyProcessor,
/// <summary> Yield time slice to any other thread on same processor </summary>
AnyThreadOnSameProcessor
}