2013-08-30 3 views
1

AFAIK, основная цель многопоточного программирования - увеличение производительности за счет использования нескольких процессорных ядер. Точка максимизирует параллельное выполнение.Какова цель классов, защищенных потоками данных?

Когда я вижу классы, основанные на потоковой передаче данных, я чувствую некоторую иронию. Поскольку средства обеспечения безопасности потоков обеспечивают последовательное выполнение (блокировка, атомарная операция или что-то еще), это антипараллельно. Thread-safe классы означает, что сериализация инкапсулирована и скрыта в классе, поэтому мы получим больше шансов принудительно выполнить серийное исполнение - потеря производительности. Было бы лучше управлять этим критическим сектором в более крупной (или самой большой) логике устройства - приложения.

Итак, почему люди нуждаются в потокобезопасных классах? Какова их реальная польза?


P.S. Я имел в виду класс, защищенный потоками - класс имеет только потокобезопасные методы, которые можно безопасно вызывать из нескольких потоков одновременно. Safe означает, что он гарантирует правильный результат чтения/записи. Правильно означает, что его результат равен результату при однопоточном выполнении. (Например, избегая ABA проблемы)

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

+3

Как бы вы хотели общаться между двумя разными потоками, если у вас не было потокобезопасного способа обмена данными? –

+0

Вопрос: Что вы подразумеваете под «потоковым безопасным классом»? [К цитатам] (http://stackoverflow.com/questions/1344025/how-to-make-a-class-thread-safe): «Люди используют этот термин, как будто это означает что-то конкретное, когда на самом деле это просто означает «работает правильно в сценарии X».Без спецификации для «правильно» и утверждения о том, что такое X, вы не можете реально что-то реализовать и знаете, что решили ту проблему, которая у вас действительно есть ». – paulsm4

+0

@ paulsm4 Я добавил дополнительный текст к своему вопросу. сделать смысл понятным. – Eonil

ответ

3

Структуры данных, защищенные потоками, могут быть реализованы без сериализации. Это сложно сделать правильно, но это выполнимо и сделано. Тогда у вас есть преимущества параллелизма без каких-либо узких мест.

6

Я думаю, что у вас вопрос, есть ложное предположение: операции синхронизации просто не являются антипараллельными. Просто нет возможности построить параллельную изменяемую структуру данных без какой-либо синхронизации. Да, тяжелое использование этих механизмов синхронизации будет отвлекать от способности кода работать параллельно. Но без этих механизмов было бы невозможно написать код в первую очередь.

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

3

Часто это связано с тем, что критический многокритериальный код с критическими характеристиками позволяет избежать использования «потокобезопасных» контейнеров. Контейнеры, такие как std :: vector и т. Д., Не являются потокобезопасными. Если приложение нуждается в совместном доступе к этим контейнерам среди разных потоков, то приложение отвечает за управление этим доступом.

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

Конечно, лучший вариант - иметь ваш торт и съесть его, например, некоторые блокировки очереди, которые позволяют одному потоку подавать очередь, а другой - без блокировки (полагаясь только на атомную природу некоторых основных операций).

3

Классы, защищенные потоками, означают, что сериализация инкапсулирована и скрыта в классе, поэтому мы получим больше шансов принудительно выполнить серийное исполнение - потеря производительности.

Обеспечивая безопасность потока, клиент несет ответственность за инкапсуляцию (не всегда). В зависимости от контекста/дизайна безопасность потоков может быть либо очень сложной, либо подвержена изменениям со временем (прерывает вашу программу при изменении API), или они просто неравномерны. Синхронизация абстрактности не должна приравниваться к потере; у него также есть потенциал для больших преимуществ - особенно потому, что это не предмет для новичков.

Было бы лучше управлять этими критическими разделами в более крупной (или самой большой) логике устройства - приложения.

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

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

Почему люди нуждаются в потокобезопасных классах? Какова их реальная польза?

Несколько хороших причин, приходят на ум:

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

  2. Некоторые структуры очень специализированы. Они могут быть неблокирующими, полагаться на атомику или использовать менее типичные параллельные шаблоны или формы синхронизации. Пример. По умолчанию вы можете просто использовать мьютекс, когда вам нужна блокировка, но иногда лучше использовать rwlock или spinlock. Иногда непреложность может быть лучше.

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

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

  5. Инкапсуляция. Иногда инкапсуляция может привести к увеличению производительности в параллельных системах. Пример: член или параметр могут быть условно неизменными, и этот признак может быть использован. В других случаях инкапсуляция может привести к более низким приобретениям или уменьшению блокировки. Другим случаем является то, что инкапсуляция может уменьшить сложность использования интерфейса - целые категории потенциальных проблем с потоками могут быть удалены (хотя у вас может быть меньше набора ограничений).

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

Есть конечно минусы, но это не ваш вопрос;)

1

Это все зависит скорее от того, что класс.

Рассмотрите очередь. Не каждая очередь должна быть потокобезопасной. Но в некоторых случаях для структуры данных, безусловно, существует потребность в том, что вы можете надавить «материал» из одного потока, а другой поток вытащить «материал» из. Это улучшает параллелизм потоков, поскольку он фокусирует связь между потоками в одном месте: очередь между потоками. Одна сторона заполняет последовательность команд, а другая читает их и выполняет их, когда это возможно. Если команд нет, он блокирует или делает что угодно.

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

Это не «антипараллельный»; его улучшает параллелизм. Без этого вам нужно будет найти другой способ для двух потоков связи. Тот, который более чем вероятно заставит одного из них блокировать чаще.

Рассмотрите shared_ptr. Стоимость изготовления контрольного счетчика shared_ptr тривиальна рядом с очень вероятной возможностью того, чтобы кто-то его завинтил. Конечно, это не бесплатно; атомный приращение/декремент не является бесплатным. Но это far от «принудительного выполнения серийного исполнения», поскольку любой момент «серийного исполнения» настолько короток, что не имеет никакого отношения к какой-либо реальной программе.

Итак, нет, эти вещи не являются «антипараллельными».

Смежные вопросы