Используя критические разделы

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