У меня высокоприоритетный процесс, который должен передавать данные низкоприоритетному процессу. Я написал базовый кольцевой буфер для обработки передачи данных:
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 () или обновление до конца не является атомарным, что приводит к ошибке.
Я мог бы поставить взаимный доступ вокруг доступа, чтобы начать и закончить, но это вызвало бы инверсию приоритета, если поток с высоким приоритетом должен ожидать блокировки, полученной потоком с низким приоритетом.
Возможно, я смогу что-то решить, используя атомарные операции, но я не знаю, какая хорошая кроссплатформенная библиотека предоставляет их.
Существует ли стандартная схема кольцевого буфера, позволяющая избежать этих проблем?