« Предыдущий пост | На главную страницу | Следующий пост »

"Критическая секция": функции Lock() и Unlock()

В прошлом выпуске я начал рассказывать о критических секциях и привел исходный код функций, с помощью которых эти критические секции реализуются: Lock() и Unlock().

В этом выпуске я хотел остановится на этих функциях подробнее.

Напомню, что критические секции используются для того, чтобы в каждый момент времени только один эксперт имел доступ к ресурсу (например, к переменной).

Критическая секция - это объект, который может находиться только в двух состояниях:

  1. "зеленый свет" (-1); и
  2. "красный свет" (1).

Перед использованием ресурса мы должны вызвать функцию Lock(). В качестве объекта "критическая секция" мы будем использовать глобальную переменную, имя которой содержится в переменной critical_section.

Первым делом в функции Lock() мы проверяем, существует ли "объект", т.е. глобальная переменная. Если она не существует, то мы ее создаем:

   // проверим, существует ли переменная critical_section
    if (!GlobalVariableCheck(critical_section))
      {
       if (GetLastError()!=0) return(1);
// переменная не существует, создадим ее if (GlobalVariableSet(critical_section, -1.0)==0) return(1); // переменная создана }

В случае каких-то ошибок вернем 1. При создании же переменной присвоим ей значение -1.0 ("зеленый свет").

Далее в течение timeout секунд в цикле пытаемся дождаться "зеленого света". По умолчанию ждем бесконечно (если параметр timeout равен нулю).

Чтобы не "зависнуть" в этом цикле, мы делаем ряд проверок. Прежде всего мы проверяем, не зажегся ли "зеленый свет". А если он зажегся, то пытаемся установить "красный свет":

       // проверить, не загорелся ли "зеленый свет"
        if (GlobalVariableGet(critical_section)==-1.0)
          {
           // "зеленый свет" загорелся, зажигаем "красный свет"
           if (GlobalVariableSetOnCondition(critical_section, 1.0, -1.0)) return(0);
// нас опередили, поэтому ждем "зеленового света" }

Далее проверяем, не был ли остановлен эксперт:

        // проверим, не остановлен ли эксперт
        if (IsStopped()) return(2);

Также проверим, не истекли ли наши timeout секунд:

        // таймаут не истек?
        if (timeout!=0)
          {
            if ((GetTickCount()-StartTime)>timeout*1000) return(3);
          }

Если же пока нет повода прервать бесконечный цикл, то мы "спим" 0.1 секунды (функция Sleep) и повторяем все сначала.

Функция Unlock() работает по аналогии: проверяем, существует ли глобальная переменная и создаем ее, если надо:

    // проверим, существует ли переменная critical_section
    if (!GlobalVariableCheck(critical_section))
      {
       if (GetLastError()!=0) return(1);
// переменная не существует, создадим ее if (GlobalVariableSet(critical_section, -1.0)==0) return(1);
// переменная создана, поэтому выходим return(0); }

Далее в бесконечном цикле мы пытаемся установить "зеленый свет" и если нам это удалось, то выходим:

    // бесконечный цикл
    while (true)
      {
        // пытаемся установить "зеленый свет"
        if (GlobalVariableSetOnCondition(critical_section, -1.0, 1.0)) return(0);
... }

Естественно, что также в цикле мы проверяем, не остановлен ли эксперт:

        // проверим, не остановлен ли эксперт
        if (IsStopped()) return(2);

И проверяем, не истек ли таймаут:

       if (timeout!=0)
          {
            if ((GetTickCount()-StartTime)>timeout*1000) return(3);
          }

Если нет повода выйти из цикла, то спим 0.1 секунды и повторяем все снова:

    Sleep(100);

Пример использования функций Lock() и Unlock():

  // вызываем Lock() перед началом работы с ресурсом
  Lock();
// работаем с ресурсом // ...
// вызываем Unlock() сразу же после завершения работы с ресурсом Unlock();

В следующем выпуске я продолжу изучение функций для работы с глобальными переменными.




Все статьи по теме "Пишем советников для MetaTrader 4".

« Предыдущий пост | На главную страницу | Следующий пост »

Подписаться на мою рассылку



Размещение статьи ""Критическая секция": функции Lock() и Unlock()" на Вашем сайте

Размещение статьи ""Критическая секция": функции Lock() и Unlock()" на Вашем сайте возможно при условии выполнениия следующих условий:

  • Запрещается изменение оригинального текста без согласия автора - Андрея Ведихина.
  • Должен быть указан первоисточник. В случае публикации в интернете Вы должны разместить следующий код гиперссылки без изменений:
  • Запрещается коммерческое использование материалов, взятых с блога "Интернет-трейдинг на форекс / forex". Доступ к ним должен быть свободным, без взимания какой-либо платы, без обязательной регистрации и/или заполнения опросного листа (анкеты) и т.д.

В случае выполнения данных условий не требуется согласия автора блога "Интернет-трейдинг на форекс / forex" на размещение статьи ""Критическая секция": функции Lock() и Unlock()" на Вашем сайте.

Журнал FOREX MAGAZINE:



Архив номеров FOREX MAGAZINE
Котировки Forex:

Счетчики:

Авторские права © 2005-2006 Андрей Ведихин

Условия использования материалов блога "Интернет-трейдинг на форекс / forex"

Контакты с автором:


Движок сайта:
Movable Type 5.04