Для чего нужна безопасность без потоков? - PullRequest
15 голосов
/ 07 января 2011

Существует множество статей и обсуждений, объясняющих, почему полезно создавать поточно-ориентированные классы. Говорят, что если доступ к нескольким потокам, например, поле в то же время, могут быть только некоторые плохие последствия. Итак, какой смысл хранить не поточно-безопасный код? Я сосредоточен в основном на .NET, но я считаю, что основные причины не зависят от языка.

например. Статические поля .NET не являются потокобезопасными. Каков будет результат , если они будут потоко-безопасными по умолчанию? (без необходимости выполнять «ручную» блокировку). Каковы преимущества использования (на самом деле по умолчанию) не-потокобезопасности?

Одна вещь, которая приходит мне в голову, - это производительность (хотя, скорее, предположение). Это довольно интуитивно понятно, что когда функция или поле не должны быть потокобезопасными, это не должно быть. Однако вопрос в том, зачем? Потокобезопасность - это просто дополнительный объем кода, который вам всегда нужно реализовать? В каких случаях я могу быть уверен на 100%, например, поле не будет использоваться двумя потоками одновременно?

Ответы [ 9 ]

15 голосов
/ 07 января 2011

Написание потокобезопасного кода:

  1. Требуется больше опытных разработчиков
  2. Сложнее и требует больше усилий для кодирования
  3. Сложнее тестировать и отлаживать
  4. Обычно имеет большую стоимость производительности

Но!Потокобезопасный код не всегда нужен.Если вы можете быть уверены, что какой-то фрагмент кода будет доступен только одному потоку, приведенный выше список станет огромным и ненужным.Это похоже на аренду фургона, когда вы едете в соседний город, когда вас двое и мало багажа.

11 голосов
/ 07 января 2011

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

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

5 голосов
/ 07 января 2011

Потокобезопасность не является предложением "да" или "нет".Значение «безопасность потока» зависит от контекста;это означает «безопасное одновременное чтение, небезопасное одновременное чтение»?Означает ли это, что приложение может просто вернуть устаревшие данные вместо сбоя?Есть много вещей, которые это может означать.

Основная причина не делать класс "потокобезопасным" - это стоимость.Если тип не будет доступен для нескольких потоков, нет смысла вкладывать в работу и увеличивать стоимость обслуживания.

5 голосов
/ 07 января 2011

Итак, какой смысл хранить код, не поддерживающий потоки?

Стоимость.Как вы и предполагали, производительность обычно снижается.

Кроме того, написание потокобезопасного кода является более сложным и трудоемким процессом.

3 голосов
/ 07 января 2011

Написание многопоточного кода иногда очень сложно. Например, простая отложенная загрузка требует двух проверок для '== null' и блокировки. Это действительно легко испортить.

[EDIT]

Я не хотел сказать, что ленивая загрузка с резьбой была особенно трудной, это «О, и я не забыл заблокировать это первым!» моменты, которые наступают быстро и тяжело, когда вы думаете, что закончили с блокировкой, которая действительно является проблемой.

2 голосов
/ 13 января 2011

Переверните этот вопрос с ног на голову.

В первые дни программирования не было никакого Thread-Safe кода, потому что не было понятия о потоках.Началась программа, затем пошагово до конца.События?Что это такое?Потоки?А?

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

Я понимаю, что вопрос направлен больше на разработчиков приложений, чем наскажем, разработчики прошивки, но взгляд на весь лес действительно дает представление о том, как развивалось это дерево.

2 голосов
/ 08 января 2011

Итак, какой смысл хранить код, не поддерживающий потоки?

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

Как уже упоминали другие, это позволяет снизить сложность и повысить производительность.

Рико Мариани написал две статьи, озаглавленные " Установкаваша синхронизация на правильном уровне Установка вашей синхронизации на правильном уровне - решение , у которого есть хороший пример этого в действии.

В статье у него есть методназывается DoWork().В нем он называет другие классы Read дважды Write дважды и затем LogToSteam.

Read, Write и LogToSteam все имели общую блокировку и были поточно-ориентированными.Это хорошо, за исключением того факта, что из-за того, что DoWork был также поточно-ориентированным, все операции синхронизации в каждом из Read, Write и LogToSteam были пустой тратой времени.

Все это связано с природой императивного программирования.Его побочные эффекты вызывают необходимость в этом.

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

2 голосов
/ 07 января 2011

Бывают ситуации, когда «потокобезопасность» не имеет смысла. Это соображение является дополнением к более высокому навыку разработчика и увеличению времени (разработка, тестирование и время выполнения все решают задачи).

Например, List<T> - это широко используемый класс, не поддерживающий потоки. Если бы мы создали потокобезопасный эквивалент, как бы мы реализовали GetEnumerator? Подсказка: хорошего решения нет.

0 голосов
/ 08 января 2011

So, what is the point of keeping non thread-safe code?

Основное правило - избегать блокировок в максимально возможной степени.Код Ideal является входящим и безопасным для потоков без какой-либо блокировки.Но это была бы утопия.

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

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

Например, рассмотрим функцию foobar(), которая получаетновые данные для каждого вызова и использует switch() case для типа данных, чтобы изменить узел в дереве.В большинстве случаев блокировки можно избежать (если не полностью), поскольку каждый оператор case будет касаться отдельного узла в дереве.Это может быть более конкретный пример, но я думаю, что это развивает мою точку зрения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...