简体   繁体   English

shmat返回分段错误(核心已转储)

[英]shmat returns segmentation fault(core dumped)

Im trying to write into shared memory but for some reason after i call shmat() and strcpy i get segmentation fault(core dumped) why is that? 我试图写入共享内存,但是由于某种原因,在我调用shmat()和strcpy之后,我遇到了分段错误(核心转储),这是为什么吗?

This is my code: 这是我的代码:

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");

edit: I have file name shmdemo.c on the directory, and the errno of shmget say "File exists" but when i delete "shmdemo.c" from the directory, a new errno comes in the ftok that say "No such file or directory". 编辑:我在目录上具有文件名shmdemo.c,并且shmget的errno说“文件存在”,但是当我从目录中删除“ shmdemo.c”时,ftok中出现了一个新的errno,说“没有此类文件或目录”。

Thank you, Asaf. 谢谢,阿萨夫。

Answerifying the various comments. 回答各种评论。 When you call: 你打电话时:

shmget(..., IPC_CREAT | IPC_EXCL);

what you're saying with the flags is: Create a new shared memory segment for this key, and make sure no shared memory segment exists with that key already. 使用标志说明的是:为此密钥创建一个新的共享内存段, 确保该密钥已经不存在共享内存段。

If you only use: 如果仅使用:

shmget(..., IPC_CREAT);

you're saying: If a shared memory segment already exists with this key, return it; 您的意思是:如果此键已经存在共享内存段,请返回它; otherwise create a new one for this key and return that. 否则 ,为此密钥创建一个新密钥并将其返回。

Generally, you probably don't want the second variant of the call. 通常,您可能不希望调用的第二种形式。 Concurrency is hard enough without adding any nondeterminism of your own. 并发足够困难,而又不增加自己的不确定性。 (Ie just letting whichever of a bunch of cooperating processes comes first create the shared memory; as opposed to having a designated "owner" process.) (也就是说,首先让一组协作进程中的任何一个先创建共享内存;而不是拥有指定的“所有者”进程。)

When using the first call, if a shared memory segment already exists at the given key, the syscall fails with the errno value EEXISTS . 使用第一个调用时,如果给定键处已经存在共享内存段,则系统调用将失败,并出现errnoEEXISTS SysV IPC are persistent, so they don't get automatically cleaned up after your program exits like, say, file descriptors. SysV IPC是持久性的,因此在程序退出(例如文件描述符)后不会自动清除它们。 (In fact, they're more analogous to temporary files.) (实际上,它们更类似于临时文件。)

You should clean them up in your program using something like shmctl(shmid, IPC_RMID, NULL); 您应该使用shmctl(shmid, IPC_RMID, NULL);类的东西在程序中清理它们shmctl(shmid, IPC_RMID, NULL); . You can also check for stray IPC objects using ipcs and remove the ones left behind with ipcrm or cleanipcs . 您还可以使用ipcs检查是否有杂散的IPC对象,并使用ipcrmcleanipcs删除残留的cleanipcs

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM