2

我试图写入共享内存,但由于某种原因,在我调用 shmat() 和 strcpy 之后,我得到了分段错误(核心转储),这是为什么?

这是我的代码:

int fd,shmid;
key_t shmkey;
char *shm_add;
pid_t pid,pid1=0,pid2=0;

shmkey=ftok("shmdemo.c",'j');
if ( shmkey == (key_t)-1 )
 {
    printf("main: ftok() for shm failed\n");
    return -1;
}
shmid=shmget(shmkey, 50, 0666 | IPC_CREAT | IPC_EXCL);
if (shmid == -1)
{
    printf("main: shmget() failed\n");
    return -1;
}
shm_add=(char *)shmat(shmid,0,0);
if ( shm_add==NULL )
{
    printf("main: shmat() failed\n");
    return -1;
 }

strcpy(shm_add,"hello");

编辑:我在目录上有文件名 shmdemo.c,并且 shmget 的 errno 说“文件存在”但是当我从目录中删除“shmdemo.c”时,新的 errno 出现在 ftok 中,说“没有这样的文件或目录”。

谢谢你,阿萨夫。

4

2 回答 2

2

回答各种意见。你打电话时:

shmget(..., IPC_CREAT | IPC_EXCL);

你用标志说的是:为这个键创建一个的共享内存段,确保该键已经不存在共享内存段。

如果您只使用:

shmget(..., IPC_CREAT);

你是说:如果一个共享内存段已经存在这个键,返回它;否则为这个键创建一个新的并返回它。

通常,您可能不想要调用的第二个变体。在不添加任何您自己的不确定性的情况下,并发已经足够难了。(即只让一堆合作进程中的任何一个首先创建共享内存;而不是指定一个“所有者”进程。)

使用第一次调用时,如果给定键处已存在共享内存段,则系统调用将失败并返回errnovalue EEXISTS。SysV IPC 是持久的,因此它们不会在您的程序退出后自动清理,例如文件描述符。(实际上,它们更类似于临时文件。)

您应该在程序中使用类似shmctl(shmid, IPC_RMID, NULL);. 您还可以使用 或 来检查杂散的 IPC 对象ipcs并删除留下的ipcrm对象cleanipcs

于 2013-05-19T20:22:01.383 回答
0

尝试删除IPC_EXCL标志并检查程序。

于 2013-05-19T16:03:28.580 回答