Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Разделяемые данные

Введение | Синхронизация потоков | Потоки и дескрипторы | Подсчет ссылок | Реализация параллельного потока | Менеджер потоков | Синхронное взаимодействие |


Читайте также:
  1. B. Перепишите и письменно переведите данные выше предложения на русский язык
  2. B. Перепишите и письменно переведите данные выше предложения на русский язык
  3. B. Перепишите и письменно переведите данные выше предложения на русский язык
  4. B. Перепишите и письменно переведите данные выше предложения на русский язык.
  5. II. Данные объективного обследования.
  6. IX. Данные лабораторных и инструментальных методов исследования.
  7. Status praesens (Данные объективного обследования).

Задача, которую нужно решить при совместном использовании данных заключается в обеспечении атомарности (неделимости) изменения данных, что иногда обозначается термином "транзакция". Иными словами, необходим взаимно-исключающий доступ к данным - недопустимо, чтобы один поток читал данные, в то время как другой поток их изменял. Наиболее простое и эффективное средство - это использование критической секции. Delphi определяет оболочку для критической секции - класс TCriticalSection в модуле SyncObjs. Модуль GsvThread имеет идентичный класс TGsvLatch, отличающийся от TCriticalSection только именами методов (вместо имени Enter используется Lock, а вместо Leave - Unlock).

Использовать критическую секцию (защелку) очень просто:

Latch.Lock;try // использование разделяемых данных....finally Latch.Unlock;end;

Блок try-finally позволяет разблокировать критическую секцию даже при возникновении исключительной ситуации. Опускать try-finally допустимо только при очень простом коде, в котором ошибка исключена. У критической секции есть одно очень важное достоинство - высокая эффективность, поскольку критическая секция - это не объект ядра операционной системы, а запись (record) в адресном пространстве приложения, именно поэтому критическая секция решает задачу синхронизации потоков только в рамках одного приложения. Альтернативное и более универсальное средство - мьютекс, более чем на порядок уступает критической секции по эффективности. В качестве недостатков критической секции можно отметить следующие:

Последний недостаток можно исправить, если применить более сложную технику, основанную не на критических секциях, а на событиях - это делает стандартный Delphi-класс TMultiReadExclusiveWriteSynchronizer.

Задача реализации взаимоисключающего доступа всегда сталкивается с принципиальной проблемой взаимной блокировки при одновременном захвате более чем одного ресурса. Предположим, что существуют два потока A и B, а также два совместно используемых ресурса R1 и R2. Далее предположим такой сценарий: поток A захватывает ресурс R1, а затем ресурс R2 (не освобождая при этом ресурса R1). Поток B захватывает ресурc R2, а затем ресурс R1. Если после того как поток A захватил R1, поток B захватит ресурс R2, то оба потока попадут в состояние дедлока (взаимоблокировки) из которого никогда не выйдут. Обнаружение и предотвращение дедлока в общем случае весьма сложная задача, поэтому требуется очень аккуратно программировать ситуацию захвата нескольких ресурсов: либо отказаться от множественного захвата, введя поток-посредник, либо захватывать ресурсы всегда только в одном и том же порядке.

Несколько уменьшить трудности, связанные с критическими секциями, можно, если инкапсулировать разделяемые данные в специально разработанных классах. Например, можно представить себе такую реализацию разделяемого списка - отдельно список TList и отдельно критическая секция для его защиты. Поскольку каждую операцию со списком требуется выполнять внутри критической секции, то программировать такие разделяемые данные очень неудобно и опасно - легко пропустить ограничение операции критической секцией. Если же объединить TList и критическую секцию в одном классе и защитить каждую операцию критической секцией, то подобных ошибок можно избежать. Именно такая цель была поставлена при реализации потокозащищенного списка в стандартном Delphi-классе TThreadList. К сожалению, таких потокозащищенных классов в Delphi совсем немного и в большинстве случаев их приходится кодировать самостоятельно.


Дата добавления: 2015-07-20; просмотров: 89 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Взаимодействие с VCL-потоком| Асинхронное взаимодействие

mybiblioteka.su - 2015-2024 год. (0.007 сек.)