тест на равенство для атомарных переменных в C и GCC - PullRequest
2 голосов
/ 12 апреля 2011

У меня есть фиктивный вопрос об атомарных переменных, использующих gcc. Моя машина поддерживает функцию __sync_add_and_fetch; Я использую этот вызов в потоке A, чтобы установить my_variable (int) .

Я хочу, чтобы поток B считывал эту общую переменную, чтобы проверить ее по значению, например, 20. Правильно ли написать следующее

   if( __sync_bool_compare_and_swap( &my_variable, 20, 20 ) ){
          //..Ok! It is 20 so go ahead!
   }else{
          // wrong: it is not ok.
   }

Если я не ошибаюсь в gcc, __sync_val_compare_and_swap может завершиться ошибкой, если в разделяемой переменной есть гонка, но я не знаю, что она возвращает; как это работает с __sync_bool_compare_and_swap?

Проблема в том, что происходит, когда одновременно поток А изменяет значение с помощью __sync_fetch_and_add? Всегда ли гарантируется, что он вернет значение этого события суммы, когда __sync_bool_compare_and_swap запущен одновременно?

В идеале и для моих целей мне действительно нужна была бы функция, выполняющая только атомарный READ, или обмен. Имеет ли C или gcc что-то подобное?

Большое спасибо

AFG

Ответы [ 2 ]

2 голосов
/ 12 апреля 2011

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

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

Но если ничего из этого не является слишком важным, вы можете просто сделать все это без каких-либо функций __sync*, так как только один поток пишет, а другой читает;Не нужно беспокоиться о поврежденных данных.Также не нужно беспокоиться о том, что переменная актуальна, поскольку у вас есть отдельное условие гонки (значение обновляется быстрее, чем проверяется).

0 голосов
/ 12 апреля 2011

Отказ от ответственности: я не использовал операции GCC _sync, но я бы предположил, что они такие же, как в MSVC.Я верю, что это должно работать.Атомарные инструкции всегда выполняются как единое целое, чтобы предотвратить условия гонки.Теперь это предполагает, что переменная, о которой вы беспокоитесь, не сопоставлена ​​с каким-либо физическим оборудованием.

...