You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中Futex系统调用始终返回errno 14问题求助

解决futex调用返回EFAULT(无效地址)的问题

核心原因分析

EFAULT错误本质是内核无法访问你传入的futex地址,不管你用虚拟地址还是物理地址,内核只认当前进程地址空间里的有效虚拟地址,直接用物理地址肯定无效——物理地址是硬件层面的,内核不会直接处理用户传入的物理地址作为futex参数。

具体解决步骤

  • 确保futex地址在当前进程的地址空间内有效
    你要唤醒的目标进程的futex虚拟地址(0x7f9e696b3004)属于那个死锁进程的地址空间,你的唤醒进程和目标进程是独立的地址空间,直接用这个地址对唤醒进程来说是未映射的无效区域,内核自然返回EFAULT。

  • 正确的跨进程futex唤醒方式

    1. 用共享内存存放futex变量:要让两个进程能操作同一个futex,必须把futex变量放在共享内存中(比如用mmap的MAP_SHARED标志,或者shmget/shmat创建的共享内存段)。这样两个进程的虚拟地址可能不同,但会映射到同一块物理内存,内核能正确关联到同一个futex。
    2. 传递当前进程的共享内存虚拟地址:在唤醒进程中,你需要用自己进程里对应共享内存的虚拟地址调用FUTEX_WAKE,而非目标进程的虚拟地址。
  • 验证地址有效性的方法
    在唤醒进程中,可以用access系统调用先检查地址是否可访问:

    if (access((void*)your_futex_addr, F_OK) == -1) {
        perror("address not accessible");
    }
    

    如果这个调用失败,说明地址在当前进程里确实无效,得先解决内存共享的问题。

  • 禁止直接使用物理地址
    内核的futex接口只接受用户空间的虚拟地址,物理地址对用户进程无意义,内核不会将其转换为有效虚拟地址,直接传物理地址必然报错。

补充说明

你之前测试中,死锁进程的futex地址是它自身地址空间的,唤醒进程没有映射这块内存,所以内核无法访问。必须让futex变量处于跨进程共享的内存区域,才能在不同进程中通过各自的虚拟地址操作同一个futex。

内容的提问来源于stack exchange,提问作者Jacob Quisenberry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:05:05