C语言共享内存开发中ftok返回Resource temporarily unavailable问题求助
我来帮你排查这个ftok报错的问题,你遇到的ftok: Resource temporarily unavailable(对应EAGAIN错误)主要有几个关键原因,咱们一步步拆解解决:
首先修正代码里的致命语法错误
先看你代码里的这一行:
if((key = ftok(".", proj_id)) < 0); {
注意if条件后面多了一个分号;!这个分号会让if的逻辑体变成空语句,后面的花括号{}块会无条件执行——不管ftok是否成功,都会运行perror("ftok")和return -1。这时候perror打印的错误信息可能并不是ftok的真实错误,而是之前某个系统调用留下的errno值,刚好触发了"Resource temporarily unavailable"的提示。
先把这个分号删掉,改成正确的写法:
if((key = ftok(".", proj_id)) < 0) {
这是第一步,修正语法后才能准确判断ftok的真实问题。
导致ftok返回EAGAIN的核心原因及解决方法
1. proj_id取值超出有效范围
ftok的第二个参数proj_id,POSIX标准明确规定只使用它的低8位(合法取值为1-255,不能是0)。你用的3001会被系统自动截断为低8位的值(3001 % 256 = 185),虽然截断后是合法值,但部分系统对超出8位的proj_id处理逻辑异常,可能返回EAGAIN。
解决方法:把原计算出的整数转换为0-255之间的非零值,比如:
int raw_proj_id = 3001; // 你的原始计算值 int proj_id = raw_proj_id % 256; if (proj_id == 0) proj_id = 1; // 避免出现无效的0值
2. 无法访问指定的文件/目录
你传入ftok的路径是.(当前目录),如果你的进程没有权限读取当前目录的元数据(比如i-node号),ftok就会失败。
解决方法:
- 检查当前目录的权限,用
ls -ld .查看,确保进程拥有读权限 - 换一个确定有读权限的固定文件路径,比如你应用程序的可执行文件路径,或者专门创建一个用于生成key的空文件(确保这个文件不会被删除或重命名,因为
ftok依赖文件的i-node号和proj_id生成唯一key)
3. 系统资源暂时不足
极少数情况下,系统内部获取文件i-node信息的资源暂时耗尽,会返回EAGAIN。这种情况可以尝试重试调用ftok:
int retries = 3; key_t key = -1; while (retries-- > 0) { key = ftok(".", proj_id); if (key != -1) break; if (errno != EAGAIN) break; // 非暂时错误直接停止重试 sleep(1); // 等待1秒后再尝试 } if (key == -1) { perror("ftok"); return -1; }
最后提醒一句:ftok生成的key依赖文件的i-node号,如果文件被删除重建,哪怕文件名相同,i-node号也会变化,生成的key也会跟着改变。所以尽量用一个不会被删除的固定文件来生成key,比用目录更可靠。
内容的提问来源于stack exchange,提问作者Aleksander

