简体   繁体   中英

shared memory folder in Mac error shm: Invalid argument

I usually code C in linux. I am using now a Mac and I am new on this machine.

In linux when I use shared memory between process, the memory is allocated as a file which pathname is /dev/shm/resource_name .

I was trying a simple code and suddenly I got an error. It wasn't able to call a function destroy() to destroy the shared memory.

Usually when this happens I delete the file manually on the directory.

My question is: Where is located the shared memory in OS X. Because when I try recompile and execute, the gcc compiler tells me that the resource already exists and I don't know how to delete it.

#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdlib.h>

int increment (int n)
{
  n = n + 1;
  printf ("%d\n", n);
  return n;
}

int *create ()
{
  int *ptr;
  int ret;

  int fd= shm_open ("/shm", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  if (fd == -1) {
    perror ("shm");
    exit (1);
  }

  ret = ftruncate (fd, sizeof (int));
  if (ret == -1) {
    perror ("shm");
    exit (2);
  }

  ptr = mmap (0, sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,   0);
  if (ptr == MAP_FAILED) {
    perror ("shm-mmap");
    exit (3);
  }
  return ptr;
}

void destroy (int *ptr)
{
  int ret;
  ret = munmap (ptr, sizeof (int));
  if (ret == -1) {
    perror ("shm");
    exit (7);
  }
  ret = shm_unlink ("shm");
  if (ret == -1) {
    perror ("shm");
    exit (8);
  }
}

int main (int argc, char *argv[])
{
  sem_t *semaphore; 
  int *ptr = create ();
  int numProcessesChilds, numIncrements;
  int i;
  if (argc == 3) {
    numProcessesChilds = atoi (argv [1]);
    numIncrements = atoi (argv [2]);
  }
  else {
    numProcessesChilds = 10; 
    numIncrements = 1;
  }
  *ptr = 0;

  semaphore = sem_open("/semaphore", O_CREAT, 0xFFFFFFFF, 1);
  if (semaphore == SEM_FAILED) {
    perror("semaphore");
  }

  for (i = 0; i < numProcessesChilds; i++) {
    switch (fork ()) {
    case -1:
      perror ("fork");
      exit (1);
    case 0:
      sem_wait(semaphore);

      for (i = 0 ; i < numIncrements; i++) {
        (*ptr) = increment (*ptr);
      }
      sem_post(semaphore);
      exit (0);
    }
  }
  for (i = 0; i < numProcessesChilds; i++) {
    wait (NULL);
  }
  sem_close(semaphore);
  sem_unlink("/semaphore");

  printf ("Fina value: %d\n", *ptr);
  destroy (ptr);
  return 0;
}

Mac OS X , like linux is UNIX based so it handles the shared memory just like Linux. The shared memory segments you allocate are also files located in /dev/shm

To destroy the shared memory you can use the command ipcs -m or ipcs -M to view all the shared memory, look for yours and then execute ipcrm -m shmid where shmid would be the id of your shared memory. You can also do ipcrm -M shmkey using the key you assigned to it

Answered here , Mac OS being derived from BSD does not expose any entry in the file system for shared memory objects. The corresponding files in /dev/shm are Linux specific.

Under Mac OS, only shm_unlink() will do the cleanup job. The OP's example program should work upon each startup as it passes O_CREAT flag to shm_open() . If the shared memory object does not already exist, it is created otherwise it is opened as it is. As the resulting memory area pointed by ptr is reset with the instruction *ptr = 0 at the beginning of the program, everything should work properly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM