Asked  7 Months ago    Answers:  5   Viewed   508 times

I have a bit of an issue with one of my projects.

I have been trying to find a well documented example of using shared memory with fork() but to no success.

Basically the scenario is that when the user starts the program, I need to store two values in shared memory: current_path which is a char* and a file_name which is also char*.

Depending on the command arguments, a new process is kicked off with fork() and that process needs to read and modify the current_path variable stored in shared memory while the file_name variable is read only.

Is there a good tutorial on shared memory with example code (if possible) that you can direct me to?

 Answers

11

There are two approaches: shmget and mmap. I'll talk about mmap, since it's more modern and flexible, but you can take a look at man shmget (or this tutorial) if you'd rather use the old-style tools.

The mmap() function can be used to allocate memory buffers with highly customizable parameters to control access and permissions, and to back them with file-system storage if necessary.

The following function creates an in-memory buffer that a process can share with its children:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

void* create_shared_memory(size_t size) {
  // Our memory buffer will be readable and writable:
  int protection = PROT_READ | PROT_WRITE;

  // The buffer will be shared (meaning other processes can access it), but
  // anonymous (meaning third-party processes cannot obtain an address for it),
  // so only this process and its children will be able to use it:
  int visibility = MAP_SHARED | MAP_ANONYMOUS;

  // The remaining parameters to `mmap()` are not important for this use case,
  // but the manpage for `mmap` explains their purpose.
  return mmap(NULL, size, protection, visibility, -1, 0);
}

The following is an example program that uses the function defined above to allocate a buffer. The parent process will write a message, fork, and then wait for its child to modify the buffer. Both processes can read and write the shared memory.

#include <string.h>
#include <unistd.h>

int main() {
  char parent_message[] = "hello";  // parent process will write this message
  char child_message[] = "goodbye"; // child process will then write this one

  void* shmem = create_shared_memory(128);

  memcpy(shmem, parent_message, sizeof(parent_message));

  int pid = fork();

  if (pid == 0) {
    printf("Child read: %sn", shmem);
    memcpy(shmem, child_message, sizeof(child_message));
    printf("Child wrote: %sn", shmem);

  } else {
    printf("Parent read: %sn", shmem);
    sleep(1);
    printf("After 1s, parent read: %sn", shmem);
  }
}
Tuesday, June 1, 2021
 
Giovanni
answered 7 Months ago
100

Let's say I create a semaphore. If I fork a bunch of child processes, will they all still use that same semaphore?

If you are using a SysV IPC semaphore (semctl), then yes. If you are using POSIX semaphores (sem_init), then yes, but only if you pass a true value for the pshared argument on creation and place it in shared memory.

Also, suppose I create a struct with semaphores inside and forked. Do all the child processes still use that same semaphore? If not, would storing that struct+semaphores in shared memory allow the child processes to use the same semaphores?

What do you mean be 'semaphores inside'? References to SysV IPC semaphores will be shared, because the semaphores don't belong to any process. If you're using POSIX semaphores, or constructing something out of pthreads mutexes and condvars, you will need to use shared memory, and the pshared attribute (pthreads has a pshared attribute for condvars and mutexes as well)

Note that anonymous mmaps created with the MAP_SHARED flag count as (anonymous) shared memory for these purposes, so it's not necessary to actually create a named shared memory segment. Ordinary heap memory will not be shared after a fork.

Friday, June 11, 2021
 
Tak
answered 6 Months ago
Tak
43

Since you are mentioning using fork(), I assume that you are living on a *nix-System

From Unix.com

The primary way to share data between processes using UNIX IPCs are:

(1) Shared memory;

(2) Sockets:

There are other UNIX IPCs including

(3) Message Queues.

(4) Semaphores;

(5) Signals.

Your best bet (for IPCs) is to use shared memory segments, based on your post. You might need to use semaphores to insure that the shared memory operations are atomic.

A tutorial on forking and shared memory is on dev shed:

http://forums.devshed.com/c-programming-42/posix-semaphore-example-using-fork-and-shared-memory-330419.html

another more in-depth description of using multithreading (if appilcable for your application) can be found here:

https://computing.llnl.gov/tutorials/pthreads/

Friday, October 8, 2021
 
Deepanshu Goyal
answered 2 Months ago
68

If you do something like:

class MyThreadRunnable implements Runnable {
    List<String> strings;

    MyThreadRunnable(List<String> strings) {
        this.strings = strings;
    }

    public void run() {
        strings.add(getName());
    }
}

// ...

List<String> sharedStrings = new ArrayList<String>();
Thread t1 = new Thread(new MyThreadRunnable(sharedStrings));
Thread t2 = new Thread(new MyThreadRunnable(sharedStrings));

t1.start();
t2.start();

then both t1 and t2 (two different threads of the same type) will be using the same list, and see changes to it made from the other thread.

Actually, since I'm not using any synchronisation for brevity, it's also possible this would corrupt the list in some unpredictable way and cause weird errors. I strongly encourage you investigate process synchronisation, and the java.util.concurrent package when working with concurrency.

Sunday, November 7, 2021
 
mario
answered 4 Weeks ago
83

This is correct, the only thing of note is that you are creating a PRIVATE shared memory segment, which means you'll have to transmit the shmid somehow to any other process that you want to have use it.

Monday, November 8, 2021
 
Mahdi
answered 4 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share