gpt4 book ai didi

c - Select() 在阻塞时无法通过 FD_SET 识别更改

转载 作者:太空狗 更新时间:2023-10-29 15:33:03 45 4
gpt4 key购买 nike

我正在调用 FD_SET() 来设置非阻塞套接字的 write_fd,而 select() 在另一个线程中阻塞——问题是即使 fd 准备好写入,select() 仍然阻塞。

我真正想要做的是:在另一个线程中准备要为这个套接字写入的数据,然后我将套接字添加到 write_fd。select() 线程应该识别并处理准备好的数据。

select() 在阻塞时不能识别 fd 内的变化吗?如果是——是否有类似 epoll() EPOLL_CTL_MOD 而不是 FD_SET() 的东西来更新集合;或者是识别设置 select() 函数超时的更改的唯一方法?

在我看来,这不是解决方案,因为那会“很慢”并且会产生 CPU 开销......

编辑:

// This thread is running all day long ...
static void * workman() {
FD_ZERO(&fd_read);
FD_ZERO(&fd_write);
FD_SET(socketId , &fd_read);

while(1) {
// PROBLEM Keeps blocking when box() is called
select(socketId+1, &fd_read, &fd_write, NULL, NULL);

if(FD_ISSET(socketId, &fd_read)) {
// RECIVE DATA
}
else if(FD_ISSET(socketId, &fd_write)) {
FD_CLR(socketId, &fd_write);
pthread_mutex_lock(&interface.mutex);
strncpy(conn.outBuffer, interface.buffer, strlen(interface.buffer));
interface.buffer[0] = '\0';
pthread_mutex_unlock(&interface.mutex);
// SEND DATA
}
}

return 0;
}

// This function is called within another thread on user input
int box(char *content) {
pthread_mutex_lock(&interface.mutex);
// preparing the data and write it into interface.buffer if available
pthread_mutex_unlock(&interface.mutex);

FD_SET(socketId, &fd_write);

return 0;
}

最佳答案

是的,正如您所怀疑的,select() 不会检测到另一个线程对文件描述符集所做的更改。毕竟,如果没有一些神奇的机制来异步检测对特定内存位置的写入,它就无法有效地做到这一点。

而且,是的,您应该使用 epoll 接口(interface)。 epoll_wait 的手册页特别指出处理来自另一个线程的更改。

While one thread is blocked in a call to epoll_pwait(), it is possible for another thread to add a file descriptor to the waited-upon epoll instance. If the new file descriptor becomes ready, it will cause the epoll_wait() call to unblock.

但是,如果您无法使用epoll 或其他支持此类更改的文件通知接口(interface),仍然有一个解决方案。您可以使用内部 pipe(或类似的机制,例如 eventfd),使 select 在更新文件描述符后返回并重新启动套。当然,你应该小心地进行适当的锁定以避免竞争条件。同样,请务必将管道置于非阻塞模式,否则对管道写入端的 write 可能会在重负载下阻塞并可能导致程序死锁。

关于c - Select() 在阻塞时无法通过 FD_SET 识别更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17818454/

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