Потоки и чтение памяти записи - это байт или немного безопасно? - PullRequest
0 голосов
/ 01 марта 2012

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

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

Например, я могу иметь их массив и передавать много информации в форме bools.Чтение и запись является поточно-ориентированным, поскольку аппаратное обеспечение не может одновременно читать и записывать один бит.Так что никаких мусорных данных.

Возможно ли это?Это целое понятие атомных типов.

Ответы [ 3 ]

2 голосов
/ 01 марта 2012

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

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

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

Кроме того, в модели «производитель / потребитель», которая, как я полагаю, у вас есть, потребителю потребуется что-то, что будет wait() до тех пор, пока производитель не будет завершен, а производителю потребуется wait() на что-то, чтобы получить отброшенный буфер из потребитель. Ожидание блокировок (или блокирование очередей - см. Ниже) - эффективный способ сделать это.

Здесь следует рассмотреть некоторые другие вещи вместо

  • Используйте пару блокирующих очередей , чтобы потребитель ожидал в очереди, а затем добавил отброшенные буферы в очередь сброса. Производитель сделал бы обратное.
  • Вы смотрели на ByteBuffer ?
0 голосов
/ 01 марта 2012

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

http://drdobbs.com/embedded-systems/210604448?pgno=1

0 голосов
/ 01 марта 2012

Это зависит от архитектуры вашего процессора. Если у вас 32-битная архитектура, то у вас будут работать 32-битные значения, если у вас 64-битная архитектура, то 64-битные значения. Не имеет значения, используете ли вы байтовый, битовый или 16-битный тип данных char, который вы используете в своем языке программирования. Если они не меньше или равны емкости вашего процессора (32 или 64 бит).

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