Thread: Posix shared memory Q

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    127

    Posix shared memory Q

    If I have 2 apps and each one does the following:

    Code:
    void *shmaddr;
    fd = shm_open();
    ftruncate(fd, size);
    shmaddr = mmap(..., size, ..., fd);
    If either app does

    memcpy(shmaddr, "hello", 5);

    Will the other's shmaddr instantly be able to cast itself to a char * and then I can print that out? And until I do the memcpy, *shmaddr will be NULL?

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by homer_3 View Post
    If I have 2 apps and each one does the following:

    Code:
    void *shmaddr;
    fd = shm_open();
    ftruncate(fd, size);
    shmaddr = mmap(..., size, ..., fd);
    If either app does

    memcpy(shmaddr, "hello", 5);

    Will the other's shmaddr instantly be able to cast itself to a char * and then I can print that out?
    That depends on the structure of the shm object, for ex. char shmbuf[1024]; writing data to an shm object that can be read by another process depends on the arguments given to the shm_open() and mmap() calls. Specifically whether the shm object was created as "read/write" and mapped as MAP_SHARED or MAP_PRIVATE.
    Quote Originally Posted by homer_3 View Post
    And until I do the memcpy, *shmaddr will be NULL?
    Depends on whether the OS gives you a clean or dirty page.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    127
    For both apps, I'm passing O_RDWR to shm_open and MAP_SHARED to mmap. I'm also memsetting shmaddr to 0.

    One thing I wasn't sure about is if I should be checking if shmaddr == NULL or *shmaddr == NULL. I've been trying to test this myself, but even with passing O_CREAT to shm_open, I keep getting ENOENT.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by homer_3 View Post
    For both apps, I'm passing O_RDWR to shm_open and MAP_SHARED to mmap. I'm also memsetting shmaddr to 0.
    But are you creating the shm object by doing a bitwise OR of O_CREAT and O_RDWR?
    Quote Originally Posted by homer_3 View Post
    One thing I wasn't sure about is if I should be checking if shmaddr == NULL or *shmaddr == NULL. I've been trying to test this myself, but even with passing O_CREAT to shm_open, I keep getting ENOENT.
    Can't say how you are calling shm_open() and mmap() without looking at the code.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    127
    Yea, I guess it is easier when you can see the code. This is what I'm using, and it keeps giving me "shm_open failed ..." with errno being ENOENT.

    Code:
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/mman.h> 
    
    size_t shmsize = 10;
    int shmfd;
    const char *shmname = "/tmp/shmtest";
    unsigned *shmaddr;
    
    int main()
    {
    
      shmfd = shm_open(shmname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH);
    
      if(shmfd > 0)
      {
        if(ftruncate(shmfd, shmsize) != -1)
        {
    	shmaddr = (unsigned *)mmap(0, shmsize, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
    
    	if(shmaddr != MAP_FAILED)
    	{
      	  memset(shmaddr, 0, shmsize);
      	  memcpy(shmaddr, "hello", 5);
              printf("Coppied \"hello\" to shared memory.\n");
    	}else
    	{
              printf("mmap failed errno %d.\n", errno);
    	}
        }else
        {
           printf("ftruncate failed errno %d.\n", errno);
        }
      }else
      {
        printf("shm_open failed errno %d.\n", errno);
      }
    
      return 0;
    }

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    The code looks good and it runs w/o any issues on my machine, so I'm not sure where the problem is.
    Check the permissions, correct owner/group etc., on the working directory and the executable.
    Try running it as root if you're on a *nix system. And btw, what compiler and platform are you using?

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    127
    I'm using CentOS5. g++ version is 4.1.2 and I'm logged in as root.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by homer_3 View Post
    I'm using CentOS5. g++ version is 4.1.2 and I'm logged in as root.
    Don't know anything about Linux distros, but I assume when you installed CentOS5 it created a "/tmp" directory; did it or not?

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    127
    Yea, there's a /tmp directory. But even if there wasn't O_CREAT should make the path, right?

  10. #10
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by homer_3 View Post
    Yea, there's a /tmp directory. But even if there wasn't O_CREAT should make the path, right?
    Nope! the O_CREAT flag applies only to the shm object, not the path to the object.

  11. #11
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    strerror(errno) tells you whats going on. On my system shm is a device so when I do an strace on your program, I see this:
    Code:
    open("/dev/shm/tmp/shmtest", O_RDWR|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0) = -1 ENOENT (No such file or directory)
    fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb80ca000
    write(1, "shm_open failed errno 2. err: No"..., 56shm_open failed errno 2. err: No such file or directory
    ) = 56
    exit_group(0)                           = ?
    In this case you would use a name such as "/blah" or perhaps just "blah", so the problem is probably just the name you are using. A name like /tmp/shmtest is invalid here as there is no /dev/shm/tmp directory (nor can there be on my system) so it must be something like /dev/shm/somefile the program's name itself mght be a good choice for this
    Last edited by nonpuz; 03-01-2010 at 09:20 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Posix shared memory
    By rutledmj in forum C Programming
    Replies: 2
    Last Post: 10-04-2009, 09:42 PM
  2. Partly shared memory
    By DrSnuggles in forum C++ Programming
    Replies: 13
    Last Post: 01-21-2009, 03:35 AM
  3. Shared Memory semaphores?
    By Ironic in forum C Programming
    Replies: 0
    Last Post: 10-31-2008, 07:13 PM
  4. Shared memory woes
    By joshdick in forum C Programming
    Replies: 4
    Last Post: 07-28-2005, 08:59 AM
  5. Managing shared memory lookups
    By clancyPC in forum Linux Programming
    Replies: 0
    Last Post: 10-08-2003, 04:44 AM