0

I have been working for a while with interprocess communication using Boost and have managed to pass big amounts of data between multiple processes/executables in POSIX. When reading from the shared memory i simply use memcpy. However, one chunk of data is especially big (~30MB) and time-critical which makes passing data using memcpy problematic.

The goal here is to be able to pass the 30MB chunk of data from process 1 to process 2 without having to move memory, but rather having process 2 access it immediately using some sort of pointer-like behaviour. The problem I am facing here, of course, is the "limitations" of the address space.

Reading online I found that Boost offers offset_ptr, but I am unsure of if this is the right way to go.

Could someone shed some light on this problem? Any help is appreciated.

  • You could use the SystemV IPC shared memory for that. Then the first process only have to send a `GO` to the second process and both have access to the same shared memory. https://stackoverflow.com/q/5656530/3684343 is for C, but the API can be used in C++ too (just don't send objects). – mch Nov 21 '22 at 14:08
  • @mch Thank you! Does this work for different executables as well? – Carl Wikström Nov 21 '22 at 14:18
  • 1
    Yes, it is Inter Process Communication. :) The `mmap` as it is in the first answer works only with `fork`ed processes. If you have 2 executables, you have to specify the same file in both executables and make the file at least as big as the shared memory. – mch Nov 21 '22 at 14:23
  • If you're already using shared memory, why can't process 2 directly access the shared memory? why does it need to use memcpy? – user253751 Nov 21 '22 at 15:28
  • Your question is too broad for me to answer. However, I have *many* existing answers that show precisely how to do this in many situations varying from very simple to very advanced (using complicated allocator-aware datastructures). Just search my answers for inspiration: [managed_shared_memory](https://stackoverflow.com/search?tab=newest&q=user%3a85371%20managed_shared_memory), [managed_mapped_file](https://stackoverflow.com/search?tab=newest&q=user%3a85371%20managed_mapped_file), [mapped_region](https://stackoverflow.com/search?tab=newest&q=user%3a85371%20mapped_region) – sehe Nov 21 '22 at 16:45
  • @user253751 because directly accessing it by, for example, using `mapped_region::get_address()` from process 2 throws `Bus Error` since the address is in another memory space. This is as far as my understanding goes, however. Is perhaps `mmap` ing the address in process 2 a workaround? – Carl Wikström Nov 22 '22 at 08:59
  • @sehe I have decided to work with UNIX instead. Working with `shm_open` along with `mmap` seems to be best documented and used for situations such as this. I can add that I need to share `v4l2_buffer`s from one process to another and be able to directly reference the data from both ends. Using anonymous mapping wrapped in `shm_open` seems like a proper way, correct me if I'm wrong. – Carl Wikström Nov 22 '22 at 09:03
  • @CarlWikström stop thinking about objects, start thinking about memory addresses. What is the program doing that causes it to throw `Bus Error`? – user253751 Nov 22 '22 at 09:10
  • @user253751 From what I read here: https://www.boost.org/doc/libs/1_77_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_region.mapped_region_address_mapping Addresses cannot be used since the two processes do not map the same memory to the same address space. This invalidates the use of pointers – Carl Wikström Nov 22 '22 at 09:17
  • Yes but I'm asking what your program is doing, not how shared memory works. – user253751 Nov 22 '22 at 09:18
  • @user253751 The two processes open up a `shared_memory_object` with the same name. They then map it using `mapped_region`s in the same way. Process 1 copies some data to one of the regions, and when process 2 tries to read from that `mapped_region` using pointers ( `mapped_region::get_address()` ) and dereferencing it throws `Bus Error`. – Carl Wikström Nov 22 '22 at 09:21
  • What is the data? What data type? – user253751 Nov 22 '22 at 09:23
  • @user253751 I don't see the relevance, I use it as a `void *` and hard reading from it by e.g. `unsigned int i = &(int *)mem` throws. – Carl Wikström Nov 22 '22 at 09:26
  • `&(int *)mem` makes no sense. If you did `*(int*)region.get_address()` this should not throw as long as the memory is mapped. What is `region.get_size()`? – user253751 Nov 22 '22 at 09:29
  • @user253751 You're right, i meant `*(int *)mem` of course, just me being sloppy in the answer. This throws as well, although I will go back and double check but last I tried doing this it throwed. – Carl Wikström Nov 22 '22 at 09:32
  • And also shared_memory.get_size – user253751 Nov 22 '22 at 09:33
  • @user253751 You were right, it works simply using the pointer directly. It feels odd, but I guess my understanding of address spaces in different processes is still very limited. Thanks for being stubborn! :) – Carl Wikström Nov 22 '22 at 09:59
  • @CarlWikström What does "simply using the pointer directly" mean, and how is it different to what you were doing before? – user253751 Nov 22 '22 at 10:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249806/discussion-between-carl-wikstrom-and-user253751). – Carl Wikström Nov 22 '22 at 10:08

0 Answers0