Задайте атомарные операции в многозадачном коде

В коде с несколькими потоками можно использовать Polyspace® Bug Finder™, чтобы обнаружить гонки данных или Polyspace Code Prover™, чтобы перечислить потенциально незащищенные совместно используемые переменные.

Определить, защищена ли переменная, совместно использованная несколькими потоками, от параллельного доступа, проверки Polyspace, если операции на переменной являются атомарными.

Неатомарные операции

Если операция является неатомарной, Polyspace полагает, что операция включает несколько шагов. Эти шаги не должны происходить вместе и могут быть прерваны операциями в других потоках.

Например, рассмотрите эти две операции в двух различных потоках:

  • Распараллельте 1: var++;

    Эта операция является неатомарной, потому что она происходит на трех шагах: чтение var, постепенное увеличение var и обратная запись var.

  • Распараллельте 2: var = 0;

    Эта операция является атомарной, если размер var является меньше, чем размер слова на цели. Смотрите детали ниже для того, как Polyspace определяет размер слова.

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

Что Polyspace рассматривает как неатомарное

Программа автоматического доказательства кода рассматривает все операции как неатомарные, если вы не защищаете их, например, при помощи критических разделов. Смотрите Задают Определенные Операции как Атомарные.

Средство поиска ошибки рассматривает операцию как неатомарную, если оно может перевести больше чем в одну машинную команду. Например:

  • Операция может включить и операцию чтения и операцию записи. Например, var++ включает чтение значения var, увеличение значения одним и обратной записью увеличенного значения к var.

  • Операция может включить 64-битную переменную на 32-битной цели. Например, операция

    long long var1, var2;
    var1=var2;
    вовлекает два шага в копирование содержимого var2 к var1 на определенных целях.

    Polyspace использует размер Pointer для вашего Target processor type как порог, чтобы вычислить атомарность. Например, если вы используете i386 в качестве своего Target processor type, размер Pointer составляет 32 бита и Long long, и размеры Double - оба 64 бита. Поэтому Polyspace рассматривает копирование одной переменной long long или double другому как неатомарное.

    См. также Target processor type (-target).

  • Операция может включить запись возвращаемого значения вызова функции к совместно используемой переменной. Например, операция x=func() включает вызов func и запись возвращаемого значения func к x.

Обнаружить данные мчится, где по крайней мере одна из двух операций прерывания является неатомарной, включите средству проверки Средства поиска Ошибки Data race. Чтобы удалить это ограничение на средство проверки, включите Data race including atomic operations.

Задайте определенные операции как атомарные

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

Используйте один из этих методов:

  • Критические разделы

    Защитите группу операций с критическими разделами.

    Критический раздел начинается и заканчивается вызовами определенных функций. Можно использовать предопределенный набор примитивов, чтобы начать или закончить критические разделы или использовать собственные функции.

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

    Задайте критические разделы с помощью опции Critical section details (-critical-section-begin -critical-section-end).

  • Временно исключительные задачи

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

    Если группа задач временно исключительна, все операции в одной задаче являются атомарными относительно операций в других задачах.

    Задайте временное исключение с помощью опции Temporally exclusive tasks (-temporal-exclusions-file).

  • Приоритеты задач (Только Средство поиска ошибки)

    Защитите группу операций путем указывания, что определенные задачи имеют более высокие приоритеты. Например, прерывания имеют более высокие приоритеты над циклическими задачами.

    Можно задать до четырех различных приоритетов с этими опциями (с самым высоким приоритетом, перечисленным сначала):

    Все операции в задаче с более высоким приоритетом являются атомарными относительно операций в задачах с более низкими приоритетами. См. также Задают Прерывания Preemptable и Задачи Nonpreemptable (Polyspace Bug Finder).

  • Прерывания отключения стандартной программы (Только Средство поиска ошибки)

    Защитите группу операций путем отключения всех прерываний. Используйте опцию Disabling all interrupts (-routine-disable-interrupts -routine-enable-interrupts).

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

Для примера смотрите Меры защиты для Совместно используемых переменных в Многозадачном Коде.

Смотрите также

| | |

Похожие темы