Гигачат Вот пример реализации простой двойной буферизации на языке C:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 1024
// Описываем структуру буферов
typedef struct {
char *buffers[2]; // два массива
int current_write_buffer; // индекс текущего буфера записи
int current_read_buffer; // индекс текущего буфера чтения
size_t buffer_size; // размер каждого буфера
} DoubleBuffer;
void init_double_buffer(DoubleBuffer* db, size_t size) {
if (!db || size <= 0)
return;
db->buffer_size = size;
for(int i = 0; i < 2; ++i) {
db->buffers[i] = malloc(size);
memset(db->buffers[i], '\0', size); // инициализируем нулями
}
db->current_write_buffer = 0;
db->current_read_buffer = 1;
}
void destroy_double_buffer(DoubleBuffer* db) {
if (!db)
return;
for(int i = 0; i < 2; ++i) {
free(db->buffers[i]);
}
}
// Функция записи данных в буфер
size_t put_data(DoubleBuffer* db, const void* data, size_t len) {
if(!db || !data || len > db->buffer_size)
return 0;
memcpy(db->buffers[db->current_write_buffer], data, len);
db->current_write_buffer ^= 1; // переключаем индексы
return len;
}
// Функция чтения данных из буфера
size_t get_data(DoubleBuffer* db, void* out_buf, size_t max_len) {
if(!db || !out_buf || max_len > db->buffer_size)
return 0;
memcpy(out_buf, db->buffers[db->current_read_buffer], max_len);
db->current_read_buffer ^= 1; // переключаем индексы
return max_len;
}
int main() {
DoubleBuffer db;
init_double_buffer(&db, BUFFER_SIZE);
char write_data[] = "Hello from the first buffer!";
char read_data[BUFFER_SIZE];
printf("Writing to first buffer...\n");
put_data(&db, write_data, strlen(write_data));
printf("Reading from second buffer...\n");
get_data(&db, read_data, sizeof(read_data));
printf("%s\n", read_data);
destroy_double_buffer(&db);
return 0;
}
```
### Пояснения:
1. **Структура `DoubleBuffer`** — хранит массивы двух буферов, индексы текущих буферов чтения/записи и размер буферов.
2. **Инициализация (`init_double_buffer`)**: выделяет память под каждый из двух буферов и устанавливает начальные значения индексов.
3. **Запись (`put_data`)**: копирует данные в текущий буфер записи и переключает индекс для следующего заполнения.
4. **Чтение (`get_data`)**: извлекает данные из текущего буфера чтения и переключает индекс для следующей операции чтения.
5. **Освобождение памяти (`destroy_double_buffer`)**: освобождает выделенную память.
Таким образом, этот код реализует простую двойную буферизацию, где один буфер используется для записи, пока другой читается, обеспечивая непрерывность операций ввода-вывода.