尝试附加共享内存的已使用地址时出错

时间:2011-11-02 22:25:00

标签: c linux unix shared-memory

使用shmget且第二个参数不为NULL时接收消息“无效参数”。

它编译正常,但在执行时,我收到了错误消息。

我整天都被困在这里。希望你能帮我! :)

#include <sys/ipc.h>        
#include <sys/shm.h>        
#include <stdlib.h>     
#include <stdio.h>          


int main()
{
    int idSharedMem;
    int *varSharedMem1;
    int *varSharedMem2;

    /* Create the shared memory */
    idSharedMem = shmget((key_t) 0001, sizeof(int), IPC_CREAT | 0666);

    if (idSharedMem == -1)
    {
        perror("shmget");
    }

    /* Allocate a memory address and attached it to a variable */
    varSharedMem1 = shmat(idSharedMem, NULL, 0);

    if (varSharedMem1 == (int *) -1)
    {
        perror("shmat1");
    }

    /* Sign a value to the variable */
    *varSharedMem1 = 5;

    /* Attach an existing allocated memory to another variable */
    varSharedMem2 = shmat(idSharedMem, varSharedMem1, 0);

    if (varSharedMem2 == (int *) -1)
    {
        /* PRINTS "shmat2: Invalid argument" */
        perror("shmat2");
    }

    /* Wanted it to print 5 */
    printf("Recovered value %d\n", *varSharedMem2);

    return(0);
}

2 个答案:

答案 0 :(得分:4)

使用shmat(idSharedMem, varSharedMem1, 0);,您尝试在varSharedMem1位置附加细分。但是,您之前在该位置附加了一个段,这将导致EINVAL。 Linux提供了一个SHM_REMAP标志,可用于替换先前映射的段。

shmat手册页:

  

可以在shmflg中指定(特定于Linux的)SHM_REMAP标志   表明该段的映射应该替换任何现有的   映射在从shmaddr开始并继续的范围内          细分的大小。 (通常,如果此地址范围中已存在映射,则会导致EINVAL错误。)在此   case,shmaddr不能为NULL。

答案 1 :(得分:1)

来自shmat手册页:

If shmaddr isn't NULL and SHM_RND is specified in shmflg, the attach occurs at the
address equal to shmaddr rounded  down  to  the nearest multiple of SHMLBA. 
Otherwise shmaddr must be a page-aligned address at which the attach occurs.

更多来自shmat手册页:

Using shmat() with shmaddr equal to NULL is the preferred, portable way of 
attaching a shared memory segment.

要进行第二次附加,只需:

varSharedMem2 = shmat(idSharedMem, NULL, 0);