2016-11-21 11 views
0

Я создаю буфер, к которому будут обращаться некоторые потоки.Объявление 'volatile' типа данных, которое должно использоваться потоками

struct buffer { 
    struct items[32]; 
    int numItems = 0; /*will keep track of number of items in the buffer 
};      and will be updated by threads when accessed. 
         We'll include mutex locking*/ 

Должен ли я declate buffer быть летучими или сделать numItems летучий?

Что я думаю: я понимаю, что волатильность должна использоваться для предотвращения оптимизации компиляторами операций между атомарным доступом данных по потокам. Пожалуйста, исправьте меня, если я не понимаю этого

Спасибо!

+2

Не пытайтесь использовать 'volatile' для обеспечения безопасности потоков. –

+1

Не беспокойтесь об изменчивости; это бесполезно, если ваша цель - правильная многопоточная программа. Вместо этого вам понадобится более сильная juju (например, locks/mutexes/atomics). http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming –

+1

@JonathanLeffler. Проблема OPs - это не безопасность потоков, а некорректная оптимизация переменных, которые используются из внутренних потоков (функции обратного вызова). – Lundin

ответ

2

Если вы хотите, чтобы предотвратить компилятор от переназначения, слияния или refetching читает или пишет, используйте летучий доступа (uint8_t тип представляет собой пример):

*(volatile uint8_t *) p = *(uint8_t *) res; 

Если ваш тип заполнителя и один доступ невозможен, используйте memcpy с барьерами памяти до и после звонок. Вы можете организовать их так же, как Linux, с READ_ONCE/WRITE_ONCE, см. here и here.

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

-3

Qualifier volatile не используется для многопоточности.

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

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

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

+2

Источник? Что именно гарантирует, что переменные, защищенные мьютексом, не будут оптимизированы? – Lundin

+1

@ 2501, _multiple_ reads/write все еще могут быть оптимизированы внутри критических разделов, а не через границы критического раздела. –

+0

@ Lundin Какая претензия такова? – 2501