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

非fork进程间设备文件描述符共享:pidfd系列系统调用的实现问询

非fork进程间设备文件描述符共享:pidfd系列系统调用的实现问询

看起来你找对路子啦!Linux 5.6版本引入的pidfd_open和pidfd_getfd这两个系统调用,确实能解决你这种非fork进程间传递文件描述符的需求,还不用依赖UNIX套接字,完美贴合你的场景。

先明确下你的核心需求:在一个进程里打开设备文件,然后在另一个完全独立的非亲缘进程中关闭这个设备描述符,对吧?你已经尝试着手写代码验证这个方案,先把你给出的open_device.c代码整理完善下:

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h> // 代码里用到printf,需要补充这个头文件

#define pidfd_open(pid, flags) syscall(SYS_pidfd_open, pid, flags)

int main() {
    // Open the device
    int fd = open("/dev/null", O_RDWR);
    if (fd == -1) {
        perror("open");
        return EXIT_FAILURE;
    }

    printf("File descriptor for /dev/null: %d\n", fd);

    // Get the current process ID
    pid_t pid = getpid();

    // Obtain a pidfd for this process
    int pidfd = pidfd_open(pid, 0);
    if (pidfd == -1) {
        perror("pidfd_open");
        close(fd);
        return EXIT_FAILURE;
    }

    // 这里可以把pid或者pidfd传递给另一个进程,比如打印出来让用户手动输入,或者通过本地文件/环境变量传递
    printf("Current process PID: %d, pidfd: %d\n", pid, pidfd);

    // 保持进程运行,等待另一个进程完成操作
    pause();

    close(pidfd);
    close(fd);
    return EXIT_SUCCESS;
}

这里要提醒你几个关键细节,避免踩坑:

  • 你提到的pidfd_getfd调用中,第二个参数要填目标进程里实际的设备文件描述符(也就是上面代码里的fd变量),而不是固定的0——0对应的是目标进程的标准输入fd,可不是你要的设备fd哦
  • 调用pidfd_getfd的进程需要足够权限:要么和目标进程拥有相同的UID,要么具备CAP_SYS_PTRACE权限,不然会返回权限错误
  • 两个进程之间需要传递PID或者pidfd:比如你可以在第一个进程里打印PID,然后在第二个进程里手动输入;或者通过本地文件、环境变量等轻量方式传递,完全不用UNIX套接字

给你补充一个对应的close_device.c示例,用来在另一个进程中获取设备fd并关闭:

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>

#define pidfd_open(pid, flags) syscall(SYS_pidfd_open, pid, flags)
#define pidfd_getfd(pidfd, fd, flags) syscall(SYS_pidfd_getfd, pidfd, fd, flags)

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <target_pid> <target_device_fd>\n", argv[0]);
        return EXIT_FAILURE;
    }

    pid_t target_pid = atoi(argv[1]);
    int target_device_fd = atoi(argv[2]);

    int pidfd = pidfd_open(target_pid, 0);
    if (pidfd == -1) {
        perror("pidfd_open");
        return EXIT_FAILURE;
    }

    // 从目标进程获取设备fd
    int device_fd = pidfd_getfd(pidfd, target_device_fd, 0);
    if (device_fd == -1) {
        perror("pidfd_getfd");
        close(pidfd);
        return EXIT_FAILURE;
    }

    printf("Got device fd: %d, closing it...\n", device_fd);
    close(device_fd);
    close(pidfd);

    return EXIT_SUCCESS;
}

测试的时候,先运行open_device,它会打印出设备fd和进程PID;然后另开一个终端,运行close_device <目标PID> <设备fd>,就能完成跨进程关闭设备的操作啦。

备注:内容来源于stack exchange,提问作者Droll80

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 06:59:55