Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ОСиСП.doc
Скачиваний:
68
Добавлен:
11.05.2015
Размер:
1.78 Mб
Скачать

24. Синхронизация программных потоков в среде .Net. Атомарные (Interlocked-операции). Семейство lnterlocked-методов

Эти методы работают очень быстро (по сравнению с другими конструкциями синхронизации потоков) и просты в применении. Недостаток один: очень ограниченные возможности. В классе System.Threading.lnterlocked определено несколько статических методов, которые могут автоматически изменять переменную безопасно для потоков. Методы, оперирующие переменными типа Int32, используются наиболее часто:

public static class Interlocked

{

// Автоматически выполняет (location++).

public static Int32 Increment(ref Int32 location);

// Автоматически выполняет (location--).

public static Int32 Decrement(ref Int32 location);

// Автоматически выполняет (locationi += value).

// ПРИМЕЧАНИЕ: значение может быть отрицательным числом,

// что позволяет выполнять вычитание.

public static Int32 Add(ref Int32 location, Int32 value);

// Автоматически выполняет (locationi = value).

public static Int32 Exchange(ref Int32 location, Int32 value);

// Автоматически выполняет следующее:

// if (locationi == comparand) locationi = value

public static Int32 CompareExchange(ref Int32 locationi, Int32 value, Int32 comparand);

}

Все Interlocked-методы требуют, чтобы передаваемый адрес переменной был корректно выровнен, иначе генерируется исключение DataMisalignedException. CLR автоматически выравнивает поля типов, если атрибут [StructLayout(LayoutKind.Explicit)] не применен к типу, а атрибут [FieldOffcet(...)] не применен к отдельным полям и принудительно не нарушает их выравнивание.

В классе Interlocked также есть методы, оперирующие переменными Int64. Никогда не следует вызывать эти методы, поскольку CLR не обеспечивает корректное выравнивание таких переменных.

25. Прерывание программных потоков в среде .Net. Особенности исключительной ситуации класса ThreadAbortException.

ThreadAbortException - Исключение, выдаваемое при вызове метода Abort. Этот класс не может наследоваться.

При вызове метода Abort для уничтожения потока, общеязыковая среда выполнения выдает исключение ThreadAbortException. Исключение ThreadAbortException является особым исключением, которое может быть перехвачено, но снова возникает в конце блока catch. При возникновении этого исключения среда выполнения перед тем, как завершить поток, выполняет все блоки finally. Так как поток может выполнять код в блоках finally неограниченное время или вызывать метод Thread.ResetAbort для отмены аварийного завершения потока, нет гарантии, что поток когда-либо закончит работу. Чтобы дождаться окончания работы прерванного потока можно вызвать метод Thread.Join. Вызов метода Join является блокирующим, возврата не происходит до действительного окончания выполнения потока.

Когда среда CLR останавливает фоновые потоки после того, как все потоки переднего плана в управляемом исполняемом файле завершились, метод Thread.Abort не используется. Следовательно, нельзя использовать перехват исключения ThreadAbortException для обнаружения прерывания фоновых потоков средой CLR.