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

В этом разделе описывается, как использовать критические разделы для защиты фрагментов кода адаптера. В разделе описывается основной класс критического раздела набора адаптеров 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<> класс шаблона из библиотеки стандартных шаблонов. The auto_ptr помогает гарантировать, что IAutoCriticalSection указатель удален.

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

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

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

    _mySection = imaqkit::createCriticalSection();
    

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

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

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

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

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

    Можно использовать IAutoCriticaSection::leave() функция, но это не обязательно. The 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;
    }