关闭fd时,我会收到epoll的通知吗? [英] Do I get a notification from epoll when a fd is closed?

查看:140
本文介绍了关闭fd时,我会收到epoll的通知吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在构建使用 epoll 的东西.效果很好,但是当底层 fd 关闭时,从 epoll 中删除文件描述符时,有一个通知会很好.

I am currently building something that uses epoll. It works pretty nice, but it would be good to have a notification when a file descriptor gets removed from epoll when the underlying fd is closed.

是否有办法在 fd 关闭后立即从 epoll 获取通知?

Is there a way to get a notification from epoll as soon as an fd is closed?

推荐答案

否.这是一个 Zig 程序来演示:

No. Here's a Zig program to demonstrate:

const std = @import("std");

pub fn main() !void {
    const epollfd = blk: {
        const rc = std.os.linux.epoll_create1(std.os.linux.EPOLL_CLOEXEC);
        const err = std.os.linux.getErrno(rc);
        if (err != 0) return error.EpollCreateFailed;
        break :blk @intCast(i32, rc);
    };
    defer std.os.close(epollfd);

    var pipe: [2]i32 = undefined;
    {
        const rc = std.os.linux.pipe2(&pipe, std.os.linux.O_CLOEXEC);
        const err = std.os.linux.getErrno(rc);
        if (err != 0) return error.PipeCreateFailed;
    }

    var ev: std.os.linux.epoll_event = undefined;

    ev.events = std.os.linux.EPOLLIN | std.os.linux.EPOLLET;
    ev.data.fd = pipe[0];
    {
        const rc = std.os.linux.epoll_ctl(epollfd, std.os.linux.EPOLL_CTL_ADD, pipe[0], &ev);
        const err = std.os.linux.getErrno(rc);
        if (err != 0) return error.EpollCtlFailed;
    }

    const thread = try std.os.spawnThread(pipe[0], threadStart);

    var events: [10]std.os.linux.epoll_event = undefined;
    const nfds = blk: {
        std.debug.warn("epoll wait\n");
        const rc = std.os.linux.epoll_wait(epollfd, &events, @intCast(u32, events.len), -1);
        std.debug.warn("epoll wakeup\n");
        const err = std.os.linux.getErrno(rc);
        if (err != 0) return error.EpollWaitFailed;
        break :blk rc;
    };
    if (nfds != 1) return error.NotExactly1FileDescriptor;
    std.debug.assert(events[0].data.fd == pipe[0]);
    thread.wait();
}

fn threadStart(fd: i32) void {
    std.os.time.sleep(1, 0);
    std.debug.warn("close fd\n");
    std.os.close(fd);
}

它输出:

epoll wait
close fd
^C

(我必须用Ctrl + C杀死它,因为它永远不会醒来.)

(I had to kill it with Ctrl+C because it never woke up.)

这是strace的输出:

Here's the strace output:

execve("./test", ["./test"], 0x7fff311ff208 /* 122 vars */) = 0
epoll_create1(EPOLL_CLOEXEC)            = 3
pipe2([4, 5], O_CLOEXEC)                = 0
epoll_ctl(3, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLET, {u32=4, u64=4}}) = 0
mmap(NULL, 8388608, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0) = 0x7fd082ed9000
clone(child_stack=0x7fd0836d8fd8, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID|0x400000, parent_tidptr=0x7fd0836d8fe4, child_tidptr=0x7fd0836d8fe4) = 13547
strace: Process 13547 attached
[pid 13546] write(2, "epoll wait\n", 11epoll wait
<unfinished ...>
[pid 13547] nanosleep({tv_sec=1, tv_nsec=0},  <unfinished ...>
[pid 13546] <... write resumed> )       = 11
[pid 13546] epoll_wait(3,  <unfinished ...>
[pid 13547] <... nanosleep resumed> 0x7fd0836d8f20) = 0
[pid 13547] write(2, "close fd\n", 9close fd
)   = 9
[pid 13547] close(4)                    = 0
[pid 13547] exit(0)                     = ?
[pid 13547] +++ exited with 0 +++
^Cstrace: Process 13546 detached

这篇关于关闭fd时,我会收到epoll的通知吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆