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

32位与64位进程间POSIX信号量同步异常问题求助

32位与64位进程POSIX信号量同步异常排查与解决

问题核心分析

你遇到的现象是内核维护的信号量实际值与32位进程sem_getvalue返回值不一致,而非信号量同步功能失效。Ubuntu 20.04的32位librt库(POSIX实时库)存在兼容性问题,导致32位进程读取64位进程创建的命名信号量时,sem_getvalue返回错误值,但信号量的实际同步逻辑(sem_wait/sem_post)仍正常工作。

验证与排查步骤

  1. 确认信号量对象一致性
    64位进程创建信号量后,Linux会在/dev/shm目录生成对应文件(命名为sem.my_sem,对应你指定的/my_sem)。执行以下命令查看inode号:

    ls -i /dev/shm/sem.my_sem
    

    32位进程打开信号量后再次执行该命令,若inode号一致,说明两个进程操作的是同一个内核信号量对象。

  2. 验证信号量实际功能
    忽略sem_getvalue的错误输出,通过同步操作验证信号量真实状态:

    • 64位进程创建信号量(初始值1)后保持运行,不调用sem_wait
    • 32位进程调用sem_wait,若立即返回成功(无阻塞),说明信号量实际值为1,sem_getvalue显示错误
    • 32位进程调用sem_post后,64位进程再调用sem_getvalue,值会恢复为1

修复方案

1. 补全32位依赖库

确保系统安装了完整的32位实时库支持:

sudo apt install lib32stdc++6 lib32z1 librt:i386

2. 绕过sem_getvalue显示问题

若补全库后问题仍存在,可通过同步操作间接判断信号量状态,而非依赖sem_getvalue的输出。例如:

  • 用sem_wait的阻塞行为判断信号量是否可用
  • 用sem_trywait立即返回结果判断当前值是否大于0

3. 升级系统版本

Ubuntu 22.04及后续版本修复了部分32位/64位进程间POSIX信号量的兼容性问题,升级系统可彻底解决该bug。

示例代码

64位进程(创建信号量)

#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main() {
    sem_t *sem = sem_open("/my_sem", O_CREAT | O_EXCL, 0666, 1);
    if (sem == SEM_FAILED) {
        perror("sem_open (64-bit)");
        return 1;
    }

    int val;
    sem_getvalue(sem, &val);
    printf("64-bit: sem value = %d\n", val);

    sleep(30); // 等待32位进程操作

    sem_getvalue(sem, &val);
    printf("64-bit after operation: sem value = %d\n", val);

    sem_close(sem);
    sem_unlink("/my_sem");
    return 0;
}

编译命令:gcc -pthread -lrt sem64.c -o sem64

32位进程(打开并操作信号量)

#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main() {
    sem_t *sem = sem_open("/my_sem", O_RDWR);
    if (sem == SEM_FAILED) {
        perror("sem_open (32-bit)");
        return 1;
    }

    int val;
    sem_getvalue(sem, &val);
    printf("32-bit: sem_getvalue returns %d\n", val);

    // 验证实际同步功能
    if (sem_wait(sem) == 0) {
        printf("32-bit: sem_wait succeeded immediately (sem value was 1)\n");
        sem_post(sem);
    } else {
        perror("sem_wait");
    }

    sem_getvalue(sem, &val);
    printf("32-bit after post: sem_getvalue returns %d\n", val);

    sem_close(sem);
    return 0;
}

编译命令:gcc -m32 -pthread -lrt sem32.c -o sem32

内容的提问来源于stack exchange,提问作者Nicolas LAURENT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:41:33