Безопасность потока и битовое поле - PullRequest
5 голосов
/ 31 мая 2011

Я знаю, что битовые поля зависят от компилятора, но я не нашел документации о безопасности потоков в битовых полях с последними версиями g ++ и Visual C ++ 2010.

Выполняет ли операции над битовыми полямичлен атомный?

Ответы [ 5 ]

5 голосов
/ 31 мая 2011

«Потокобезопасный», к сожалению, очень перегруженный термин в программировании.

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

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

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

Помогает ли это?

Редактировать : Д-р.У Дана Гроссмана есть две прекрасные лекции по атомарности и синхронизации, которые я нашел на странице отдела CS в UOregon .

2 голосов
/ 01 июня 2011

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

Если вы практически не можете использовать отдельные переменные для рассматриваемых битовых полей, вы можете хранить несколько битовых полей в целых числах и обновлять их атомарно, создавая объединение между структурой битовых полей и 32-битной целое число, а затем с использованием последовательности CompareExchange:

  1. Считать значение битового поля как Int32.
  2. Преобразуйте его в структуру битового поля.
  3. Обновить структуру
  4. Преобразование структуры обратно в Int32.
  5. Используйте CompareExchange, чтобы перезаписать переменную новым значением, только если оно все еще содержит значение, считанное в (1); если значение изменилось, начните заново с шага (1).

Чтобы этот подход работал хорошо, шаги 2-4 должны быть быстрыми. Чем дольше они занимают, тем больше вероятность того, что CompareExchange на шаге 5 завершится неудачей, и, следовательно, чем больше шагов 2-4 придется выполнять повторно, прежде чем CompareExchange будет успешным.

1 голос
/ 31 мая 2011
1 голос
/ 31 мая 2011

Если вы хотите обновить битовые поля потокобезопасным способом, вам нужно разделить ваши битовые поля на отдельные флаги и использовать обычные int s для их хранения. Доступ к отдельным машинным словам является поточно-ориентированным (хотя необходимо учитывать оптимизацию и когерентность кэша в многопроцессорных системах).

0 голосов
/ 28 октября 2012

просто используйте atomic.AddInt32 пример:

atomic.AddInt32(&intval, 1 << 0)      //set the first bit
atomic.AddInt32(&intval, 1 << 1) //set the second bit
atomic.AddInt32(&intval, -(1 << 1 + 1 << 0)) //clear the first and second bit

код написан на Go, я думаю, что в c ++ также есть что-то вроде atomic.AddInt32

...