gpt4 book ai didi

c - 不同线程中的多个 epoll_wait 接收不是为它们设计的事件

转载 作者:太空宇宙 更新时间:2023-11-04 11:35:12 27 4
gpt4 key购买 nike

我有两次调用 event_wait。
线程 1:监听来自子进程的管道

        struct epoll_event *ev;
struct EpollStub stub[pool->plugins.count];
...
epollfd = epoll_create1(0);
if (epollfd == -1) {
return -1;
}
ev->events = EPOLLIN;
for(int i=0;i<plugins->count;i++) {
inf = &plugins->stp[i];
stub[i].type = EREAD_STAP;
stub[i].pointer = inf;
ev->data.ptr = stub+i;
if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, inf->fd, ev) == -1) {
close(epollfd);
return -1;
}
}
do {
n = epoll_wait(pool->epollfd, evs, EPOLL_EVENTS_MAX, -1);
for(int i=0;i<n;i++) {
ev = evs + i;
struct EpollStub *stub = (struct EpollStub *)ev->data.ptr;
if(stub->type!=EREAD_STAP) {
#ifdef __MDEBUG
printf("EREAD: Wrong event: %d\n",stub->type);
#endif
continue;
}
else {
// inf = (struct StpInfo*)ev->data.ptr;
inf = (struct StpInfo*)stub->pointer;
fd = inf->fd;
#ifdef __MDEBUG
printf("EREAD fd: %d\n",fd);
#endif
///do something here
}
....

线程 2:监听客户端套接字

    struct epoll_event ev;
pool->epollfd = epoll_create1(0);
if (pool->epollfd == -1) {
return -1;
}
ev.events = EPOLLIN;
for(int i=0;i<pool->sockets.count;i++) {
struct EpollStub *stub = &pool->sockets.stub[i];
stub->type = EACCEPT_CONN;
stub->pointer = pool->sockets.fd[i];
ev.data.ptr = stub;
if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, (int)stub->pointer, &ev) = -1) {
return -1;
}
}
...

cfd = epoll_wait(pool->epollfd, &ev, 1, -1);
if(is_working(pool,cfd)) {
struct EpollStub *stub = (struct EpollStub *)ev.data.ptr;
if(stub->type!=EACCEPT_CONN) {
#ifdef __MDEBUG
printf("EACCEPT: Wrong event: %d\n",stub->type);
#endif
}
else {
#ifdef __MDEBUG
printf("EACCEPT fd: %d\n",(int)stub->pointer);
#endif
break;
///do something here
}
}
....

内核:opensuse-3.1.0-1.2-desktop
他们从彼此那里获取事件。我制作 EpollStub 只是为了确保他们得到。如果没有这个第一个事件返回一个指针,第二个返回一个句柄,结果是在接收描述符并将其用作指针时出现段错误。
我不认为这是正常行为。这是内核中的错误还是我哪里错了?

最佳答案

这是您代码中的错误。您在一些地方将 pool->epollfdepollfd 混淆了,例如:

    epollfd = epoll_create1(0);
if (epollfd == -1) {
return -1;
}
ev->events = EPOLLIN;
for(int i=0;i<plugins->count;i++) {
inf = &plugins->stp[i];
stub[i].type = EREAD_STAP;
stub[i].pointer = inf;
ev->data.ptr = stub+i;
if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, inf->fd, ev) == -1) {
close(epollfd);
return -1;
}
}
do {
n = epoll_wait(pool->epollfd, evs, EPOLL_EVENTS_MAX, -1);

您创建 epollfd,然后修改 pool->epollfd 并等待它。如果你有两个不同的事件集,你需要使用两个不同的 epoll fds。

epoll 机制是完全线程不可知的。它不绑定(bind)事件或设置到线程。任何线程都可以在集合中添加或删除描述符。任何线程都可以获得任何集合的事件。

关于c - 不同线程中的多个 epoll_wait 接收不是为它们设计的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8515225/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com