Что делает членов экземпляра небезопасными потоком по сравнению с общедоступными помехами?

Честно, Википедия могла бы быть лучшим местом для поиска ответа на это.

, Если NP = P, то мы можем решить очень тяжелые проблемы намного быстрее, чем, мы думали, что могли прежде. Если мы решаем только одну Полную NP проблему в P (многочлен) время, то это может быть применено ко всем другим проблемам в Полной NP категории.

20
задан cyberconte 8 August 2009 в 20:37
поделиться

4 ответа

Это верно только в общих чертах.

В общем, статические методы являются статическими, потому что они не зависят и не имеют доступа к каким-либо данным, определенным экземпляром, к которым может получить доступ другой поток. В общем, единственные переменные, которые они (статический метод) используют, - это переменные, объявленные и привязанные к статической памяти класса, в котором реализован метод, а не к памяти, выделенной для объекта - (экземпляра класса), созданного для этого объекта. . Статический метод не может ссылаться на любую такую ​​переменную или использовать ее. Если метод использует этот тип переменной данных экземпляра, привязанный к конкретному экземпляру, он не может быть статическим. Метод экземпляра, напротив, имеет доступ к некоторому элементу данных (свойству или полю) экземпляра.

Если, otoh, статический метод обращается к статическому свойству или полю класса, это также небезопасно для потоков.

Для того, чтобы гонка была возможна, необходимы четыре условия.

  1. Первое условие состоит в том, что есть области памяти, доступные из более чем одного потока. Как правило, эти местоположения являются глобальными / статическими переменными или представляют собой динамическую память, доступную из глобальных / статических переменных.
  2. Второе условие заключается в том, что существует свойство (часто называемое инвариантом), которое связано с этими ячейками общей памяти, которые должны быть истина или действительна для правильной работы программы. Как правило, свойство должно сохраняться до того, как произойдет обновление, чтобы обновление было правильным.
  3. Третье условие заключается в том, что свойство инварианта не сохраняется в течение некоторой части фактического обновления. (Это временно недействительно или неверно во время некоторой части обработки).
  4. Четвертое и последнее условие, которое должно произойти для возникновения гонки, - это то, что другой поток обращается к памяти, пока инвариант нарушен, что приводит к несогласованному или неправильному поведению.
16
ответ дан 30 November 2019 в 00:01
поделиться

Ошибка, потому что шаблон не подавляет неявное объявление конструктора копирования. Он будет служить простым конструктором преобразования, который можно использовать для копирования объекта, когда его выбирает разрешение перегрузки.

Итак, вы, вероятно, где-то скопировали свою матрицу, которая будет использовать неявно определенный конструктор копирования, который выполняет плоскую копию. Затем скопированная матрица и копия в своем деструкторе удаляют один и тот же указатель.

Кроме того, почему требуется чрезвычайно подробный синтаксис template template

Потому что задействованы два шаблона: Matrix, который является шаблоном класса, и конвертирующий шаблон конструктора. Каждый шаблон заслуживает отдельного предложения шаблона со своими параметрами.

Вам следует избавиться от < T> в твоей первой строке, кстати. При определении шаблона такого не происходит.

Это плохое решение, поскольку оно приводит к полному дублированию кода конструктора копирования.

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


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

struct A {
  template<typename T>
  A(T&) { std::cout << "A(T&)"; }
  A() { }
};

int main() {
  A a;
  A b(a); // template wins:
          //   A<A>(A&)  -- specialization
          //   A(A const&); -- implicit copy constructor
          // (prefer less qualification)

  A const a1;
  A b1(a1); // implicit copy constructor wins: 
            //   A(A const&) -- specialization
            //   A(A const&) -- implicit copy constructor
            // (prefer non-template)
}

Конструктор копирования может также иметь неконстантный ссылочный параметр,

14
ответ дан 30 November 2019 в 00:01
поделиться

Это проблема государства. Что общего делает методы небезопасными для нескольких потоков, так это то, что они не обращаются к общему состоянию потокобезопасным способом. Статические методы обычно не имеют доступа к общему состоянию и, следовательно, с меньшей вероятностью столкнутся с этой проблемой. По-прежнему возможно иметь условия гонки в статических / общих методах, если они касаются статических данных, но в целом статические методы этого не делают.

8
ответ дан 30 November 2019 в 00:01
поделиться

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

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

0
ответ дан 30 November 2019 в 00:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: