Understanding Shared Memory Using C

懵懂的女人 提交于 2020-01-04 02:54:32

问题


Using C, I'm trying to set up shared memory. My code looks like:

key_t key = ftok("SomeString", 1);
static int *sharedval;
int shmid = shmget(key, sizeof(int), S_IRUSR | S_IWUSR); // less permissions
sharedval = (int *) shmat(shmid, NULL, 0);
*sharedval = 0;

However the second I run that last line, I get a segmentation fault. When debugging, I can print "sharedval" and I get a memory address, presumably the place in memory I got. So I would assume all I have to do is use *sharedval to assess it, but apparently not. How am I supposed to read from the shared memory? A push in the right direction would be wonderful. Thanks!

Edit:

another.anon.coward's output:

$ ./a.out 
ftok: No such file or directory
shmget: No such file or directory
Trying shmget with IPC_CREAT
shmget success
shmat success
Segmentation fault: 11

回答1:


The problem in your case could be that there is no associated memory segment for the given key. You need to create a memory segment by passing IPC_CREAT flag in shmget in that case. Please use perror to check your error message. Use can try the following code

    #include <stdio.h> //For perror
    ...

    key_t key = ftok("SomeString", 1);
    if ( 0 > key )
    {
       perror("ftok"); /*Displays the error message*/
       /*Error handling. Return with some error code*/
    }
    else /* This is not needed, just for success message*/
    {
       printf("ftok success\n");
    }

    static int *sharedval;
    int shmid = shmget(key, sizeof(int), S_IRUSR | S_IWUSR | IPC_CREAT);
    if ( 0 > shmid )
    {
        perror("shmget"); /*Displays the error message*/
    }
    else /* This is not needed, just for success message*/
    {
       printf("shmget success\n");
    }

    sharedval = (int *) shmat(shmid, NULL, 0);
    if ( 0 > sharedval )
    {
       perror("shmat"); /*Displays the error message*/
       /*Error handling. Return with some error code*/
    }
    else /* This is not needed, just for success message*/
    {
       printf("shmat success\n");
    }
    *sharedval = 0;
    ...



回答2:


The right way to do shared memory in modern programs is with mmap and MAP_SHARED. You can use either an ordinary file or a named shared memory object created with shm_open.




回答3:


The problem is that ftok requires an existing file which can be passed to fstat and not an arbitrary string. From the man page:

key_t ftok(const char* pathname, int proj_id)

The ftok() function uses the identity of the file named by the given pathname (which must refer to an existing, accessible file) ...

An easy fix is to try:

int main(int argc, char* argv[])
{
  key_t key = ftok(argv[0], 1);
  ...
}

This also explains why you are getting an ENOENT (No such file or directory) error from ftok.




回答4:


As noted above your code is missing error checking. For example the way for shmat to indicate an error is to return -1, which when it is displayed as a pointer looks like a long int - so that very well what is happening here.

Specifically, note that ftok(), which stand for File Token, needs to get the path to a valid file on the Linux file system to derive the shared memory ID from the file inode number (it does not look at the file content). Unless you have a file in your current directory called SomeString this is why this call is failing.

Last but not least, I really recommend using POSIX shared memory API rather then the SySV API you are using. See shm_open(3) (http://linux.die.net/man/3/shm_open) for the details



来源:https://stackoverflow.com/questions/7495326/understanding-shared-memory-using-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!