У меня есть высокоприоритетный процесс, которому необходимо передать данные низкоприоритетному процессу. . Я написал базовый кольцевой буфер для обработки передачи данных:
class RingBuffer {
public:
RingBuffer(int size);
~RingBuffer();
int count() {return (size + end - start) % size;}
void write(char *data, int bytes) {
// some work that uses only buffer and end
end = (end + bytes) % size;
}
void read(char *data, int bytes) {
// some work that uses only buffer and start
start = (start + bytes) % size;
}
private:
char *buffer;
const int size;
int start, end;
};
Вот в чем проблема. Предположим, у низкоприоритетного процесса есть оракул, который точно сообщает ему, сколько данных нужно прочитать, так что count ()
никогда не вызывается. Тогда (если я чего-то не упускаю) проблем с параллелизмом нет. Однако, как только поток с низким приоритетом должен вызвать count ()
(поток с высоким приоритетом может также захотеть вызвать его, чтобы проверить, не переполнен ли буфер), существует вероятность того, что математика в count (), или обновление до конца не является атомарным, что приводит к ошибке.
Я мог бы поместить мьютекс вокруг доступа к началу и концу, но это вызовет инверсию приоритета, если высокоприоритетный поток должен ждать блокировки, полученной поток с низким приоритетом.
Я мог бы что-то решить, используя атомарные операции, но я не знаю хорошей кроссплатформенной библиотеки, обеспечивающей их.
Существует ли стандартный дизайн кольцевого буфера, позволяющий избежать этих проблем?