Достижение потокобезопасности

Вы не можете получить MAC-адрес для CBPeripheral, но вы можете получить свойство identifier, которое является UUID, который iOS вычисляет из MAC среди другой информации.

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

Его нельзя использовать на другом устройстве iOS для идентификации того же периферийного устройства.

19
задан jpfollenius 19 February 2009 в 08:13
поделиться

7 ответов

Вы не можете действительно протестировать на ориентированный на многопотоковое исполнение. Все, что можно сделать, показать, что код не ориентирован на многопотоковое исполнение, но если Вы знаете, как сделать это, Вы уже знаете, что сделать в Вашей программе для исправления той конкретной ошибки. Это - ошибки, Вы не знаете, что проблема, и как был бы Вы тесты записи на тех? Кроме этого проблемы многопоточности намного более трудно найти, чем другие проблемы, поскольку действие отладки может уже изменить поведение программы. Вещи будут отличаться от одного прогона программы до следующего от одной машины до другого. Количество центральных процессоров и ядер процессора, число и вид программ, работающих параллельно, точного порядка и синхронизирующих материала, происходящего в программе - все это и намного, больше будет иметь влияние на поведение программы. [Я на самом деле хотел добавить фазу луны и материала как этот к этому списку, но Вы получаете мое значение.]

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

я сказал бы, запускаются с статья Wikipedia о потоках и прокладывают себе путь через связанные статьи. Я запустил с книги "Win32 Многопоточное Программирование" Aaron Cohen и Mike Woodring - это распродано, но возможно можно найти что-то подобным.

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

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

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

то, Что Вы делаете, создают объекты то убывание из TInterfacedObject. Они реализуют один или несколько интерфейсов, которые все обеспечивают только доступу только для чтения к внутренностям объекта, но они могут также обеспечить открытые методы, которые видоизменяют объектное состояние. При создании объекта, Вы сохраняете и переменную типа объекта и переменную указателя на интерфейс. Тем путем управление времени жизни легко, потому что объект будет удален автоматически, когда исключение произойдет. Вы используете переменную, указывающую на объект назвать все методы необходимыми для надлежащей установки объекта. Это видоизменяет внутреннее состояние, но так как это происходит только в активном потоке нет никакого потенциала для конфликта. После того как объект правильно настраивается, Вы возвращаете указатель на интерфейс коду вызова, и так как нет никакого способа получить доступ к объекту впоследствии кроме путем прохождения через указателя на интерфейс, можно быть уверены, что только доступ только для чтения может быть выполнен. При помощи этой техники можно полностью удалить блокировку в объекте.

, Что, если необходимо изменить состояние объекта? Вы не делаете, Вы создаете новый путем копирования данных из интерфейса и видоизменяете внутреннее состояние новых объектов впоследствии. Наконец Вы возвращаете ссылочный указатель на новый объект.

При помощи этого Вам только будет нужна блокировка, где Вы получаете или устанавливаете такие интерфейсы. Это может даже быть сделано без блокировки, при помощи атомарных функций обмена. См. это сообщение в блоге Primoz Gabrijelcic для подобного варианта использования, где указатель на интерфейс установлен.

16
ответ дан 30 November 2019 в 04:12
поделиться

Я просто хотел добавить две ссылки к этому обсуждению, которое я нашел полезным при размышлении о потокобезопасности и возможностях достигнуть его:

краткий справочник А по освоению потокобезопасности

Дизайн для потокобезопасности

2
ответ дан 30 November 2019 в 04:12
поделиться

Я буду совет второго mghie: потокобезопасность разработана в. Читайте об этом где угодно, Вы можете.

Для действительно низкоуровневого взгляда на то, как это реализовано, ищите книгу по внутренностям ядра операционной системы реального времени. Хороший пример MicroC/OS-II: Оперативное Ядро Jean J. Labrosse, который содержит полный аннотируемый исходный код к рабочему ядру наряду с обсуждениями того, почему вещи сделаны путем, они.

Редактирование : В свете улучшенного вопроса, фокусирующегося на использовании функции RTL...

Любой объект, который виден больше чем одному потоку, является потенциальной проблемой синхронизации. Ориентированный на многопотоковое исполнение объект следовал бы за последовательным шаблоном в реализации каждого метода блокировки "достаточного количества" состояния объекта на время метода, или возможно, суженный только к "достаточно долго". Конечно, имеет место, что любая последовательность read-modify-write к любой части состояния объекта должна быть сделана атомарно относительно других потоков.

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

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

2
ответ дан 30 November 2019 в 04:12
поделиться

Мой простой ответ, объединенный с теми, отвечает:

  • Создают Ваше приложение с помощью способа потокобезопасности
  • , Избегают использования общедоступной статической переменной во всех местах

Поэтому, это обычно попадает в эту привычку/практику легко, но требуется некоторое время для привыкания к:

программируют Вашу логику (не UI) на языке функционального программирования, таком как F# или даже использование Схемы или Haskell. Также функциональное программирование продвигает практику потокобезопасности, в то время как это также попросило нас всегда кодировать к чистоте в функциональном программировании. При использовании F# существует также ясное различие об использовании изменяемых или неизменных объектов, таких как переменные.

<час>

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

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

1
ответ дан 30 November 2019 в 04:12
поделиться

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

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

РЕДАКТИРОВАНИЕ: Более длительный ответ на комментарий Обжимного пресса. Не вписался бы в комментарий :(

Вы полностью корректны. Вот почему мне нравится сохранять теневую копию основных данных в потоке только для чтения. Я добавляю управление версиями к структуре (один 4 выровненный DWORD) и увеличиваю эту версию в (защищенном от блокировки) устройстве записи данных. Средство чтения данных сравнило бы глобальную и частную версию (который может быть сделан, не блокируя), и только если они отличаются, это заблокировало бы структуру, копировало бы его к локальному устройству хранения данных, обновило бы локальную версию и разблокировало бы. Затем это получило бы доступ к локальной копии структуры. Работает отлично, если чтение является основным способом получить доступ к структуре.

6
ответ дан 30 November 2019 в 04:12
поделиться

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

то, Что я пытаюсь сделать:

  • Использование известный шаблон многопоточного дизайна : пул потоков , парадигма модели агента , шаблон "команда" или некоторый такой подход. Таким образом, процесс синхронизации происходит таким же образом, универсальным способом , всюду по приложению.
  • Предел и концентрат точки синхронизации . Напишите свой код, таким образом, Вам нужна синхронизация в как можно меньшем количестве мест и содержании код синхронизации в один или немного мест в коде.
  • Пишут код синхронизации так, чтобы логическое отношение между значениями было ясно и на при вводе и при выходе из защиты. Я использую много из, утверждает для этого (Ваша среда может ограничить это).
  • никогда не получают доступ к совместно используемым переменным без защиты/синхронизации . Быть очень ясным, каковы Ваши совместно используемые данные. (я услышал, существуют парадигмы для многопоточного программирования без защиты, но это потребовало бы еще большего количества исследования).
  • Пишут Ваш код максимально чисто, ясно и СУХО.
2
ответ дан 30 November 2019 в 04:12
поделиться

M2C - Параллелизм Java на практике действительно хорош.

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

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