How to share existing memory?

I wanted to write some function void* share(void*, int) , which should set up shared memory for sharing data in a pointer.

My first attempt looked (without checks, etc.):

 void* share(void *toBeShared, int size) { int fd = shm_open(SHM_NAME, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); ftruncate(fd, size); return mmap(toBeShared, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); } 

but that doesn't seem to work as I would like. The second attempt was something like this:

 void* share(void *toBeShared, int size) { void *mem = NULL; int fd = shm_open(SHM_NAME, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); ftruncate(fd, size); mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) memcpy(mem, toBeShared, size); return mem; } 

and it really works, but I need to copy all the data that I would like to avoid.

So my question is: is there a way to split the memory that has already been allocated (if possible, without having to copy too much), and if so, how can this be done?

Thanks in advance.

PS: I saw more of these questions (for example, here and here ), but there are no answers to them.


edit:

how i would like to use it:

 typedef struct { char *name; int status; } MyTask; int main(int argc, char** argv) { MyTask* taskList = NULL, sharedTaskList = NULL; int length = 0; ... readFile(&taskList, &length, ...); sharedTaskList = share(taskList, length * sizeof(MyTask)); // or maybe even better: without needing to assign it to new variable for(i = 0; i < NR_WORKERS; i++) { switch(pid = fork()) { //etc... } } ... return 0; } 
+5
source share
1 answer

How to share existing memory?

Do not use existing memory . Get some (small amount) of "fresh" shared memory and use (i.e. fill or read) later.

Assuming you're on Linux, read shm_overview (7) .

I assume that some of your functions may fail. You have to test rejection every call, for example.

 int fd = shm_open(SHM_NAME, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd<0) {perror("shm_open"); exit(EXIT_FAILURE);}; 

etc. Maybe use strace (1) as well

there is a way to share allocated memory

The short answer is no! (or not easily, not in a portable way). You usually do the opposite: get some common segment of known size and use some pointers in it. (the same common segment may have different virtual addresses in different processes, for example, due to ASLR ).

You can use mmap (2) with MAP_FIXED on some already used sub-segment of the virtual address space (which would replace and replace the mapping with a new one, do not share the existing mapping!), But I would suggest avoiding this. Please note that the virtual address space is managed by multiple pages, so there is no way to separate some data that does not align on the page. Thus, your share function is not possible if only toBeShared and size are page aligned. You can consider specific Linux mremap (2)

In other words, your applications should first allocate some shared memory, and then put / use some data inside the resulting shared segment, and not try to exchange some existing non-distributed areas of virtual memory. Therefore, you probably want to code the code void* get_my_shared_memory(); (assuming size is a compile-time constant, and you call this function once for each process, and its resulting virtual address often changes from one process to another)

In practice, memory is a finite resource, and shared memory is a limited and very limited resource. On most systems, you can share several tens of megabytes ... Therefore, the sharing of an arbitrary large amount of memory is unreasonable.

Perhaps your application may just use some kind of server, for example. some à la PostGreSQL database server to exchange information by querying this server (and using the ACID properties of the DBMS). Or you can organize it as a messaging monitoring process (for example, a processing URL) - in pipes or sockets or fifos - with slave processes. But we do not know which application you are coding.

By the way, memory sharing is not enough. You need to synchronize processes .

-4
source

Source: https://habr.com/ru/post/1241920/


All Articles