使用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);
}
答案 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);