When to Use Pipes VS When to Use Shared Memory

When to use Pipes vs When to use Shared Memory

Essentially, pipes - whether named or anonymous - are used like message passing. Someone sends a piece of information to the recipient and the recipient can receive it. Shared memory is more like publishing data - someone puts data in shared memory and the readers (potentially many) must use synchronization e.g. via semaphores to learn about the fact that there is new data and must know how to read the memory region to find the information.

With pipes the synchronization is simple and built into the pipe mechanism itself - your reads and writes will freeze and unfreeze the app when something interesting happens. With shared memory, it is easier to work asynchronously and check for new data only once in a while - but at the cost of much more complex code. Plus you can get many-to-many communication but it requires more work again. Also, due to the above, debugging of pipe-based communication is easier than debugging shared memory.

A minor difference is that fifos are visible directly in the filesystem while shared memory regions need special tools like ipcs for their management in case you e.g. create a shared memory segment but your app dies and doesn't clean up after itself (same goes for semaphores and many other synchronization mechanisms which you might need to use together with shared memory).

Shared memory also gives you more control over bufferring and resource use - within limits allowed by the OS it's you who decides how much memory to allocate and how to use it. With pipes, the OS controls things automatically, so once again you loose some flexibility but are relieved of much work.

Summary of most important points: pipes for one-to-one communication, less coding and letting the OS handle things, shared memory for many-to-many, more manual control over things but at the cost of more work and harder debugging.

Difference between shared memory and pipe in unix?

Taken from this article

(unnamed) Pipes

  • Can switch between blocking and
    non-blocking mode
  • Don't have to free them when done
  • Are automatically inherited by
    children
  • Must read and write in a linear
    fashion

Shared Memory

  • Can store structures
  • Won't ever block - positive
  • Can have as many programs read or
    write to it as you need
  • Won't ever block - negative: must use
    semaphores or your own spin-locks
  • It's possible for it to not be freed
    even when all programs exit

Pipes and sockets - message passing or shared memory ?

message passing, as they require participation on both sides, sender and receiver in case of sockets for example. they can be implemented using shared memory, but communication pattern is message passing

Are memory mapped files faster than Named Pipes?

The answer is, as usual, "It depends." If there is a lot of data involved, shared memory will cut out much of the overhead of copying it. But using a mapped file in this way still requires some adjunct form of IPC to coordinate access to the shared memory space.

Why would I need threads for implementing a 'named pipe based on shared memory'?

Roughly, your pipe-alike structure should be located in shared memory (e.g. obtained by shm_open) and contain the following members:

  • One mutex controlling all access to the structure.
  • One condition variable for signaling a waiting peer.
  • A buffer of some fixed size.
  • Two offsets into the buffer for the current read and write position.

The read function should basically obtain the mutex, then check whether there's data available for read, and if not, wait on the condition variable and loop rechecking for data. Once data is found, you'll need to signal the condition variable if the read made it possible to fit more data in the buffer to wake up a potentially-waiting writer. Copy the data read into a caller-provided buffer then unlock the mutex.

The write function should basically obtain the mutex, then check whethere there's space in the buffer left to write. If not, it should wait on the condition variable and loop rechecking for space available to write. Once space is found, it should copy the data into the buffer, signal the condition variable to wake any reader that might be waiting for data, and unlock the mutex.

Both the mutex and condition variable need to be created with the process-shared attribute it you'll be using the "pipe" for communication between processes (not just threads in the same process). You probably also need to think about whether you want to support multiple readers/writers and whether you need single-signal or broadcast-signal semantics for the condition variables. There are a lot of ways to optimize the behavior, but the above outline should give you a general starting point.



Related Topics



Leave a reply



Submit