exponenta event banner

Использование критических сечений

В этом разделе описывается, как использовать критические разделы для защиты частей кода адаптера. В этом разделе описывается класс основного критического раздела набора адаптеров. ICriticalSectionи вспомогательный класс, IAutoCriticalSection, которые используются для управления критическими разделами. Охватываемые темы включают:

Общие сведения о критических разделах

Чтобы предотвратить одновременный доступ нескольких потоков к разделам кода или ресурсам, используйте критический раздел (ICriticalSecton) объекты. Базовый процесс использования критического раздела состоит из трех этапов:

  1. Создание объекта критического сечения с помощью набора адаптеров createCriticalSection() функция.

  2. В точке кода, который требуется защитить, введите критический раздел, позвонив по ссылке ICriticalSection::enter() функция-член.

  3. В конце кода, который требуется защитить, оставьте критический раздел, вызвав ICriticalSection::leave() функция-член.

Хотя этот процесс может показаться простым, использование ICriticalSection объект непосредственно таким образом может подвергнуть адаптер проблемам. Например, если в защищенном коде возникает ошибка, вызов leave() возможно, функция никогда не будет выполнена. Ввод критического раздела, а затем никогда не выход из него может привести к неожиданным результатам.

Для упрощения работы с критическими секциями набор адаптеров предоставляет второй класс, называемый IAutoCriticalSection, это поможет управлять определяемыми критическими разделами.

Сначала создается ICriticalSection и затем передать этот объект в createAutoCriticalSection() при создании IAutoCriticalSection объект. При создании объекта автоматически вводится критическое сечение без вызова enter() функция. Когда защищенный код выходит из области действия, секция автоматического критического кода автоматически покидает критическую секцию без вызова leave() функция.

Объект автокритического сечения обеспечивает постоянный выход из критического сечения. Однако необходимо также убедиться в том, что автоматически критический раздел будет удален. Для этого набор адаптеров рекомендует управлять рукояткой IAutoCriticalSection объект, возвращен createAutoCriticalSection(), как auto_ptr с использованием std::auto_ptr<> класс шаблона из библиотеки стандартных шаблонов. auto_ptr помогает гарантировать, что IAutoCriticalSection дескриптор удален.

Пример: Использование критического сечения

Чтобы определить раздел кода как критический раздел, выполните следующую процедуру.

  1. Создание ICriticalSection объект, с использованием createCriticalSection() функция. Адаптеры обычно создают ICriticalSection объект в их конструкторах - см. раздел Реализация конструктора классов адаптеров.

    _mySection = imaqkit::createCriticalSection();
    

    Функция возвращает дескриптор ICriticalSection объект. _mySection, которая объявляется как переменная-член в файле заголовка класса адаптера следующим образом.

    imaqkit::ICriticalSection* _mySection;
    
  2. В момент кода, который требуется защитить, создайте IAutoCriticalSection объект. IAutoCriticalSection класс гарантирует освобождение объектов критического раздела при выходе защищенного кода за пределы области действия или при возникновении исключения. В адаптере обычно требуется защитить цикл захвата кадра в критическом разделе. Вставьте этот код в функцию потока получения непосредственно перед циклом получения кадра (см. раздел Реализация функции потока получения).

    std::auto_ptr<imaqkit::IAutoCriticalSection> 
    myAutoSection(imaqkit::createAutoCriticalSection(adaptor->_mySection, 
    true));
    

    В этом коде переменная myAutoSection является дескриптором для IAutoCriticalSection объект, который управляется как библиотека стандартных шаблонов auto_ptr. Код передает дескриптор ICriticalSection объект, _mySection, в качестве аргумента для createAutoCriticalSection() функция. Второй аргумент для createAutoCriticalSection() указывает, что адаптер должен автоматически входить в критическое сечение при создании IAutoCriticalSection.

  3. В конце кода, который требуется защитить, оставьте критический раздел. В адаптере необходимо оставить критический раздел после завершения цикла захвата кадра. Вставьте этот код непосредственно перед тем, как функция потока сбора данных выйдет из цикла сбора данных кадра. См. раздел Реализация функции потока сбора данных.

    Вы можете использовать IAutoCriticaSection::leave() функция, но это не обязательно. IAutoCriticalSection автоматически покидает критический раздел, когда раздел кода выходит из области действия. Возможно, потребуется включить явные вызовы leave() используется в коде для документирования объема критического раздела.

    bool MyDeviceAdaptor::stopCapture(){
    
    // If the device is not acquiring data, return. 
       if (!isAcquiring()) 
          return true;
    
    // Get the critical section and enter it.
    
       std::auto_ptr<imaqkit::IAutoCriticalSection> 
       GrabSection(imaqkit::createAutoCriticalSection(_grabSection,
                                                      true));
    
    //**********************************************************
    // Insert calls to your device's SDK to stop the device, if
    // necessary.
    //**********************************************************
    
    // Leave the critical section.
    
       GrabSection->leave();
    
       return true;
    }