msgget调用报错no such file or directory,求助消息队列课程作业问题
解决msgget()报错"no such file or directory"的问题
我之前玩System V消息队列的时候也踩过这个坑,结合Beej教程里的kirk/spock示例,给你梳理几个必查的方向:
1. 先确认消息队列的键值(key)是否完全一致
Beej的示例里,发送端kirk和接收端spock必须用同一个键值才能访问同一条消息队列。如果两边的key不匹配,msgget()自然找不到目标队列,就会抛出这个错误。
- 检查代码里的
ftok()调用:教程里应该是用ftok("某个文件名", 'B')生成key,要确保kirk.c和spock.c里的文件名、项目ID(比如那个'B')完全一样,而且这个文件必须真实存在。 - 如果是硬编码的key(比如
0xDEADBEEF),两边的数值必须丝毫不差。
2. 别忽略ftok()依赖的文件
ftok()生成key的前提是指定的文件存在(不能是目录)。如果代码里写的文件不存在,ftok()会返回-1,把这个无效key传给msgget(),就会触发"no such file or directory"。
- 手动创建教程里指定的文件:比如执行
touch somefile(对应代码里的文件名),确保文件存在且权限正常。 - 加个调试输出检查ftok的结果:在代码里加
printf("ftok生成的key: %d\n", key);,如果输出是-1,那肯定是文件路径的问题。
3. 先运行接收端创建队列
System V消息队列需要先被创建出来(必须带IPC_CREAT标志调用msgget())。如果你先跑了kirk(发送端),而spock(接收端)还没运行过,队列根本就不存在,msgget()当然找不到。
- 先启动spock.c:它的代码里应该用了
msgget(key, IPC_CREAT | 0666)来创建队列,等它运行过之后再启动kirk。 - 或者给kirk的msgget加
IPC_CREAT:比如改成msgget(key, IPC_CREAT | 0666),这样如果队列不存在会自动创建,但要注意权限设置别出问题。
4. 检查系统里的消息队列状态
如果之前运行过示例但没正确清理队列,可能系统里的队列资源已经耗尽,或者目标队列被手动删除了。
- 用
ipcs -q命令查看当前系统的消息队列列表,确认目标队列是否存在。 - 如果队列存在但权限不对,用
ipchmod调整权限,或者直接删除重建:ipcrm -q <队列ID>。
最后贴一段修正后的msgget调用示例,确保逻辑更健壮:
key_t key = ftok("somefile", 'B'); if (key == -1) { perror("ftok"); exit(1); } int msqid = msgget(key, IPC_CREAT | 0666); if (msqid == -1) { perror("msgget"); exit(1); }
内容的提问来源于stack exchange,提问作者salsaslam
相关产品推荐
相关产品推荐

