Я пытаюсь отобразить разделяемую память или выделить ее в существующую разделяемую память, используя сопоставление файлов разделяемой памяти, используя mmap.
Первая обнаруженная проблема - использование mallo c и mmap в circular_buf_init
функция. Я думаю, что malloc
не распределяется между процессами, и я нашел реализацию MAP_ANONYMOUS временным решением.
Я использую эту структуру и ее функции:
struct circular_buf_t
{
char **buffer;
size_t head;
size_t tail;
size_t max; //of the buffer
bool full;
};
cbuf_handle_t circular_buf_init(cbuf_handle_t cbuf, size_t size)
{
//cbuf_handle_t cbuf //= malloc(sizeof(circular_buf_t));
assert(cbuf);
//size_t cb = sizeof(char *) * size;
/* cbuf->buffer = (char **)malloc(sizeof(char *) * size);
for(int i = 0; i < size; i++){
cbuf->buffer[i] = (char *)malloc(sizeof(char) * 256);
} */
cbuf->buffer = (char **)mmap(cbuf->buffer, sizeof(char *) * size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
for(int i = 0; i < size; i++){
cbuf->buffer[i] = (char *)mmap(cbuf->buffer[i], sizeof(char) * 256, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
}
if (cbuf->buffer == MAP_FAILED)
exit(EXIT_FAILURE);
cbuf->max = size;
circular_buf_reset(cbuf);
assert(circular_buf_empty(cbuf));
printf("sizeof(cbuf)=%zu\n",sizeof(cbuf));
return cbuf;
}
void advance_pointer(cbuf_handle_t cbuf)
{
if (cbuf->full)
{
cbuf->tail = (cbuf->tail + 1) % cbuf->max;
}
cbuf->head = (cbuf->head + 1) % cbuf->max;
// We mark full because we will advance tail on the next time around
cbuf->full = (cbuf->head == cbuf->tail);
}
int circular_buf_put(cbuf_handle_t cbuf, char *data)
{
int r = -1;
if (!circular_buf_full(cbuf))
{
//cbuf->buffer[cbuf->head] = (char *)malloc(sizeof(char) * 256);
strcpy(cbuf->buffer[cbuf->head], data);
advance_pointer(cbuf);
r = 0;
}
return r;
}
void print_buffer_status(cbuf_handle_t cbuf)
{
printf("Full: %d, empty: %d, size: %zu\n",
circular_buf_full(cbuf),
circular_buf_empty(cbuf),
circular_buf_size(cbuf));
}
void circular_buf_reset(cbuf_handle_t cbuf)
{
cbuf->head = 0;
cbuf->tail = 0;
cbuf->full = false;
}
size_t circular_buf_size(cbuf_handle_t cbuf)
{
size_t size = cbuf->max;
if (!cbuf->full)
{
if (cbuf->head >= cbuf->tail)
{
size = (cbuf->head - cbuf->tail);
}
else
{
size = (cbuf->max + cbuf->head - cbuf->tail);
}
}
return size;
}
size_t circular_buf_capacity(cbuf_handle_t cbuf)
{
assert(cbuf);
return cbuf->max;
}
int circular_buf_get(cbuf_handle_t cbuf, char * data)
{
int r = -1;
if(!circular_buf_empty(cbuf))
{
strcpy(data,cbuf->buffer[cbuf->tail]);
retreat_pointer(cbuf);
r = 0;
}
return r;
}
bool circular_buf_empty(cbuf_handle_t cbuf)
{
return (!cbuf->full && (cbuf->head == cbuf->tail));
}
bool circular_buf_full(cbuf_handle_t cbuf)
{
return cbuf->full;
}
В моем program
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <stdbool.h>
#include <unistd.h>
#include <getopt.h>
#include "../circular_buffer/circular_buffer.h"
#include "../circular_buffer/circular_buffer.c"
#include "../shared/shared.h"
int main(int argc, char *argv[])
{
int opt, val;
size_t buffer_size;
char *buffer_name;
buffer_size = 0;
while ((opt = getopt(argc, argv, "s:n")) != -1)
{
switch (opt)
{
case 'n':
buffer_name = strdup(argv[optind]);
break;
case 's':
buffer_size = atoi(optarg);
break;
default:
fprintf(stderr, "Usage: %s [-n buffer_name] [-s buffer_size]\n",
argv[0]);
exit(EXIT_FAILURE);
}
}
if (optind >= argc)
{
fprintf(stderr, "Expected argument after options\n\tUsage: %s [-n buffer_name] [-s buffer_size]\n", argv[0]);
exit(EXIT_FAILURE);
}
printf("buffer_name argument = %s\n", buffer_name);
printf("buffer_size argument = %zu\n", buffer_size);
//create the shared memory segment
buffer_shm_fd = shm_open(buffer_name, O_CREAT | O_RDWR, 0666);
//configure the size of the shared memory segment
size_t len = sizeof(struct circular_buf_t); //+ sizeof(char *) * buffer_size * sizeof(char) * 256;
ftruncate(buffer_shm_fd, len);
//map the shared memory segment in process address space
//circular_buf_init(buffer_mem_ptr, buffer_size);
buffer_mem_ptr = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, buffer_shm_fd, 0);
circular_buf_init(buffer_mem_ptr, buffer_size);
printf("sizeof(buffer_mem_ptr) = %zu\n",sizeof(buffer_mem_ptr));
//printf("cb=%zu\n",cb);
printf("4096=%zu\n",4096);
char *s = "datos";
circular_buf_put(buffer_mem_ptr, s);
print_buffer_status(buffer_mem_ptr);
/* char data[256];
circular_buf_get(buffer_mem_ptr, data);
printf("%s ", data); */
//
if (msync(buffer_mem_ptr, sizeof(buffer_mem_ptr), MS_SYNC) == -1)
{
perror("Could not sync the file to disk");
}
free(buffer_name);
exit(EXIT_SUCCESS);
}
И второй процесс использования общей памяти - это
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <stdbool.h>
#include <unistd.h>
#include "../shared/shared.h"
#include "../circular_buffer/circular_buffer.h"
#include "../circular_buffer/circular_buffer.c"
int main()
{
const char *name = "k";
int shm_fd; //shared memory file discriptor
int buffer_size = 3;
size_t len = sizeof(struct circular_buf_t); //+ sizeof(char *) * buffer_size * sizeof(char) * 256;
/* make * shelf shared between processes*/
//create the shared memory segment
shm_fd = shm_open(name, O_RDWR, 0666);
//configure the size of the shared memory segment
ftruncate(shm_fd, len);
//map the shared memory segment in process address space
buffer_mem_ptr = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
buffer_mem_ptr->buffer = (char **)mmap(buffer_mem_ptr->buffer, sizeof(char *) * buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
for(int i = 0; i < buffer_size; i++){
buffer_mem_ptr->buffer[i] = (char *)mmap(buffer_mem_ptr->buffer[i], sizeof(char) * 256, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
}
/* creat/open semaphores*/
//cook post semaphore fill after cooking a pizza
print_buffer_status(buffer_mem_ptr);
printf("\nCook: I have started cooking pizza.\n");
char *s = "datos";
circular_buf_put(buffer_mem_ptr, s);
print_buffer_status(buffer_mem_ptr);
char data[256];
circular_buf_get(buffer_mem_ptr, data);
printf("%s ", data);
/* char *s = "datos";
circular_buf_get(buffer_mem_ptr, s);
print_buffer_status(buffer_mem_ptr); */
return 0;
}
Но я понятия не имею, как распределить это динамическое c 2d выделение массива для разделяемой памяти, используя ММАП. Пожалуйста, дайте мне обратную связь, чтобы помочь найти решение.