3

I allocated a block of shared memory using shmget.

Then I attach the shared memory to process A and process B respectively using shmat. I assume the handles(i.e.,addresses within A and B that are mapped to the actual shared memory) for A and B returned by shmat are different.

Let's assume the handles for A and B are defined as char* p and char* q respectively. My question is if we write an object to the address p + sizeof(anotherObject) within process A, can we expect to get the same object at the address q + sizeof(anotherObject) within process B?

I guess it is the case but am not 100% sure. If so, how is this communication or mapping mechanism being achieved since we know that p + sizeof(anotherObject) and q + sizeof(anotherObject) are referring to different memory locations?

2
  • Consider using Boost.Interprocess - there is a documentation that answer questions like yours. Commented Nov 29, 2011 at 17:01
  • consider using the modern interfaces shm_open and mmap for such a task. They are less restrictive and easier to handle. Commented Nov 29, 2011 at 19:49

2 Answers 2

5

Modern processors use virtual address spaces. The address, you're using in you program is not the "real" address of the objects, the operating system and the processor maps pages of memory to an address range, and you use that as "memory".

Creating a shared memory simply means that the OS maps the same memory page into two or more different processes' address spaces. The fact that the two pointers in the two processes do not have the same numeric value means nothing, even if pointers in different processes have the same numeric value, they usually point to different memory locations.

About writing the "object" to the memory, you first have to "serialize" it. I mentioned that pointers in different processes are incompatible with each other. If your object has any pointer members, or other objects that may contain pointers, you have to come up with a way to replace those pointers with the actual data, because once you read the object from the other thread, those pointers are as good as trash.

Be aware that C++ std::sting, std::vector and the other containers, along with any virtual object (object that have virtual function) have pointers inside them. so if you want to pass a string you need to write it as a sequence of characters into the shared memory, and read the same way on the other side.

Sign up to request clarification or add additional context in comments.

Comments

0

Can you write the binary representation of an object in a region of shared memory? Yes.

Can you safely use the object from the another program by accessing its binary representation stored in shared memory? Sometimes, but not generally.

The rules are similar to writing out the binary representation for serialization to disk or over a wire. You have to make sure to handle pointers to other objects, as well as all non-POD members. For instance, a std::string instance has a pointer to allocated memory which:

  1. might not be in the region of shared memory
  2. might not have the same address in the other process (e.g. the data is in shared memory, but the shared memory regions were mapped to different base addresses in both processes).

So, a simple heuristic is that if X is anything you can't:

std::ofstream file("foo.bin",std::ios::binary); file.write(reinterpret_cast<const char*>(&X), sizeof(X)); 

Then you can't safely write it out into shared memory.

Notes: even if the data is a POD type, you can't assume that writing it out is safe. On some operating systems, it's possible to run several different types of processes (e.g. 32-bit and 64-bit processes). In such a case, using types such as int might not be the same in both processes. Given a specific operating system, a specific compiler and specific compilation settings, it might be possible to derive a reliable way to write such POD types. If this environment can change, avoid doing so like the plague.

2 Comments

You can use fixed width PODs like int32_t and uint8_t to make sure both 32 and 64 bits processes can use them.
@WTP: still not guaranteed that both processes are using the same compiler and same alignment. This is much more subtle than it looks. Hence, achieving this is possible, but not guaranteed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.